home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / dos / database / salve / salve.man < prev    next >
Encoding:
Text File  |  1988-06-02  |  152.6 KB  |  7,723 lines

  1.  
  2.  
  3.                                  Copyright Ron Albury 1988
  4.  
  5.  
  6.           INTRODUCTION
  7.           INTRODUCTION
  8.  
  9.                 
  10.           SALVE SOFTWARE
  11.  
  12.                 Several years  ago I  was watching a sit-com on TV.  In it a
  13.              man had  lost his  job, and was picking up pocket money selling
  14.              some kind  of salve.   It  was never really clear what you were
  15.              supposed to use the salve for.  When ever someone would ask him
  16.              what it  was for he would say, "Use it for what ever you want".
  17.              It was a running joke for the whole episode.  In the last scene
  18.              a slightly goofy secondary character said he was running out of
  19.              salve and  wanted to buy some more.  Everyone turned to him and
  20.              asked what  he used  it for.  The answer, of course, was: "What
  21.              ever you want".
  22.  
  23.                 While I  am not  out of  a job,  I am desperately in need of
  24.              some extra  money.   I decided to develop some utility software
  25.              functions and distribute them as shareware.  These routines are
  26.              not applications  in and  of themselves.  Their purpose is just
  27.              to make your application development go a little easier.
  28.  
  29.                 What can you use Salve Software for?  Anything you want!
  30.  
  31.           SHAREWARE
  32.  
  33.                 I developed  the Salve  Data Management  Library to  make my
  34.              life, and  the lives  of other  program  developers,  a  little
  35.              easier.   If you  believe this library is a useful tool and you
  36.              want it supported and improved you should voice your support by
  37.              registering it with me.  If you are planning to use the library
  38.              frequently or  in a  revenue generating  program, please send a
  39.              contribution to:
  40.                  Ron Albury
  41.                  Salve Software
  42.                  660 Brandy Way
  43.                  Cincinnati, OH 45244.
  44.  
  45.  
  46.                 In addition  to the  above  address  you  can  reach  me  on
  47.              Compuserve [73577,121].   Due  to my  erratic schedule you have
  48.              the greatest chance of reaching me if you use EMAIL.
  49.  
  50.                 Private individuals  may register  their personal use of the
  51.              library   for   a   $20.00   contribution.      Profit   making
  52.              organizations, or  individuals using  the library  in a revenue
  53.              generating  software  program,  should  contribute  $50.00  per
  54.              development CPU.   Salve  Data Management Library may be linked
  55.              into programs  which are  subsequently released, given or sold,
  56.              without additional  licenses or  fees.   You may  not  release,
  57.              give, or  sell linkable  objects or  libraries containing Salve
  58.              Data Management  routines without prior approval.  You may move
  59.              registered libraries between systems at no additional charge as
  60.              long as the files are only available on one system at a time.
  61.  
  62.  
  63.  
  64.  
  65.                                            - 1 -
  66.  
  67.  
  68.  
  69.  
  70.                                  Copyright Ron Albury 1988
  71.  
  72.                 Source  code   is  available  for  restricted  use:  private
  73.              use/$50.00, revenue  generating/$100.00.   The source  code may
  74.              not be  released, given,  sold,  used  to  create  unregistered
  75.              copies of  the library,  or in  any way  used to circumvent the
  76.              previously  stated   restrictions.     Site   licences   and/or
  77.              unrestricted licences are negotiable.
  78.  
  79.                 This software  is protected  both by United States Copyright
  80.              Law and  international treaty provisions.  Using the Salve Data
  81.              Management Library  in a  revenue generating  program,  without
  82.              first registering, is a definite no-no.
  83.  
  84.                 This software  tool is  distributed through  public channels
  85.              and relies  on the  goodwill of its users for survival.  Please
  86.              feel free  to distribute  the shareware version of this package
  87.              to your friends, your enemies, or anyone else you can think of.
  88.              I only  ask that  you do  so without altering any of the files,
  89.              and that  all files that I have supplied to you are included in
  90.              any distribution.
  91.  
  92.                 I specifically  disclaim any  implied warranties,  and in no
  93.              way shall  I be  liable for  any loss  of profit  or any  other
  94.              damage, including  but  not  limited  to  special,  incidental,
  95.              consequential or  other damages.   If you want me to 'byte' off
  96.              that kind  of liability  you'd better  be willing  to pay a lot
  97.              more money  than I  asked for.  However, I will attempt to help
  98.              registered users  of the  package with  any technical  problems
  99.              they may  have.   I will  also attempt  to incorporate  as many
  100.              suggestions as  possible in future releases.  If you find a bug
  101.              please report  it to  me.   If I  agree that it is a bug I will
  102.              either correct  the problem  or I will refund your registration
  103.              money.
  104.  
  105.           DESIGN APPROACH
  106.  
  107.                 In  my  experience,  most  of  the  art  of  programming  is
  108.              developing and  managing data  structures.   Even Niklaus Wirth
  109.              supports this  contention with  his  book  "Algorithms  +  Data
  110.                                                         ____________________
  111.              Structures  =   Programs".    I've  developed  everything  from
  112.              _________________________                                      
  113.              business applications  to real  time factory  control software,
  114.              and in  every case the first thing I had to do was to solve the
  115.              data management problem.
  116.  
  117.                 I have  always liked  the software  class concept.  I am not
  118.                                                     _____                   
  119.              very familiar  with the  classic object oriented languages like
  120.              Smalltalk.  However I have had quite a bit of experience with a
  121.              special superset  of Pascal  that supported  the class concept.
  122.              The intent  of these  routines is  to treat a number of classic
  123.              data management  structures  as  if  they  are  just  variables
  124.              capable of  holding multiple  values.   The  functions  I  have
  125.              supplied constitute  the set  of operations  defined for  those
  126.              variables.
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.                                            - 2 -
  135.  
  136.  
  137.  
  138.  
  139.                                  Copyright Ron Albury 1988
  140.  
  141.                 I have  not provided any spiffy macros to hide the fact that
  142.              you are  accessing C  functions.  I have not introduced any new
  143.              syntax to support the illusion of a software class.  If you can
  144.                                                           _____             
  145.              not or  do not  want to  relate to  these routines  in terms of
  146.              classes, try  thinking of  them as temporary files with special
  147.              _______                            _________                   
  148.              capabilities.
  149.  
  150.                 Each instance  of a  data class  (such as a tree or a linked
  151.              list) that  you put into your program is opened up, just like a
  152.              file.  You can open up several different types data structures,
  153.              or several  instances of the same type of data structure.  When
  154.              you open  up the structure you are given a 'root' (or 'handle')
  155.              to that  instance.  From then on you use that root whenever you
  156.              access that  data class,  just as  you would with a file.  When
  157.              you are  done with  the class you close the handle, just as you
  158.              would with a file.
  159.  
  160.                 When I  was designing  the library  I had  to decide  how to
  161.              store your  data in the classes.  Each class of data management
  162.              (tree, list, hash, etc.) requires different data to support its
  163.              maintenance.   One approach would have been to have you include
  164.              some of  this support  overhead in  your data  records (such as
  165.              front and  back pointers with lists, or left and right pointers
  166.              with trees).  I decided against this approach, instead choosing
  167.              to have  you pass  a pointer to the 'bare' data record you want
  168.              stored.   It is then up to the management functions to allocate
  169.              any extra data fields necessary to link your data in.  This way
  170.              your data  records do  not have  to change, no matter what data
  171.              management technique  you use  to handle them.  Perhaps this is
  172.              not the most efficient technique in absolute cpu cycles, but it
  173.              does provide you the most flexibility in what you store and how
  174.              you store it.
  175.  
  176.  
  177.                 One aspect  of this  added flexibility  is the fact that you
  178.              can store  things other  than pointers to data structures.  The
  179.              Salve routines  know only  that you  are passing  in a  32  bit
  180.              value.     With  proper   care  it   is  possible,  under  some
  181.              circumstances, to  forgo the  overhead  of  allocating  a  data
  182.              structure and  directly store  a 32  bit value  into  the  data
  183.              management class.  Be warned, however, that if you store a zero
  184.              value in this manner, the debug library will report a non-fatal
  185.              warning
  186.  
  187.  
  188.                 There is  nothing inherently  complicated or difficult about
  189.              what I  am providing here.  Any one of you, given a little time
  190.              (actually it  took me  more than  a little  time) and  a little
  191.              motivation, would  probably do  as good  of a job as I did.  In
  192.              fact, most  of you  probably have  developed bits and pieces of
  193.              this library,  over and  over and  over again.   Like the chain
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.                                            - 3 -
  203.  
  204.  
  205.  
  206.  
  207.                                  Copyright Ron Albury 1988
  208.  
  209.              smoker said,  "It's easy  to give  up cigarettes.   I must have
  210.              done it  three or four times last year."  The challenge was not
  211.              just to write some data management routines, but to develop the
  212.              routines in  a flexible  enough way  to avoid doing it three or
  213.              four times in a year.
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.                                            - 4 -
  269.  
  270.  
  271.  
  272.  
  273.                                  Copyright Ron Albury 1988
  274.  
  275.           USE OF POINTERS IN FUNCTIONS
  276.  
  277.                 One  problem   with  passing   pointers  around  in  generic
  278.              functions is  how to  declare the  parameters in  the  function
  279.              prototypes.   The ANSI committee made things easier by allowing
  280.              void pointer ('void *') parameters.  When you need to pass to a
  281.              function a  "pointer to  a user defined record structure", that
  282.              parameter is  declared as  a void  pointer.  This allows you to
  283.              pass a  pointer to  anything without  generating a compile time
  284.              warning.
  285.  
  286.                 However, it  is less  clear how  to declare the address of a
  287.              "pointer to  a user define record structure".  If, for example,
  288.              you are  calling a  'find' function,  you must  pass into  that
  289.              function the address of your pointer so your pointer can be set
  290.              to the found data record.  If this pointer-address parameter is
  291.              declared as  'void **' you will get a compile time warning when
  292.              you pass  the address  of a  user defined  pointer.   If it  is
  293.              declared just  as 'void  *', the compile warning goes away, but
  294.              coding could  become confusing  if you  reference the parameter
  295.              definitions in  the function  prototype.  The compromise I came
  296.              up with  was to  document the parameters one way in this manual
  297.              (as void  **), and to declare them the other way in the include
  298.              file (as void *).
  299.  
  300.           FILES AND LIBRARIES INCLUDED
  301.  
  302.                 The following  files are a part of the Salve Data Management
  303.              Library:
  304.  
  305.                 READ.ME       - Last Minute Instructions
  306.                 SALVE.MAN     - Library Manual (this document).
  307.                 SALVE.H       - Include File
  308.                 SALVE#.LIB    - Optimized Library
  309.                 SALVE#D.LIB   - Debug Library
  310.                 EXAMPLE.C     - Example Program
  311.  
  312.                 The #  in the library file name is either T for Turbo-C or M
  313.              for Microsoft-C.
  314.  
  315.                 All Salve  Data Management  Functions are  compiled  in  the
  316.              Large model.   There  is no  reason inherent  in the  code that
  317.              prevents them from being compiled in the small or medium model.
  318.  
  319.                 The  Debug   library  has  the  same  functionality  as  the
  320.              Optimized library,  with additional  code included  to  provide
  321.              enhanced error  detection and  reporting.   Critical parameters
  322.              are tested for validity upon function entry, and standard C run
  323.              time library  functions that are not expected to fail in normal
  324.              production (such  as malloc)  are tested  after each  use.  All
  325.              errors which  are detected are, by default, written to the file
  326.              stdout.   The SALVE  optimized library follows in the tradition
  327.              of the  standard C  runtime library  and does very little error
  328.              checking.   The utility function 'set_error_log' can be used to
  329.              direct the error logging to a different file.
  330.  
  331.  
  332.  
  333.  
  334.                                            - 5 -
  335.  
  336.  
  337.  
  338.  
  339.                                  Copyright Ron Albury 1988
  340.  
  341.           USER SUPPLIED FUNCTIONS
  342.  
  343.              KCMPFNC
  344.  
  345.                 Three classes  of data  management (list,  tree,  and  hash)
  346.              require you  to provide  a  KCmpFnc  comparison  function  when
  347.              opening up  a handle.  This function is later used when finding
  348.              elements or  adding elements based on a key field.  The KCmpFnc
  349.              function is similar to the C run time library strcmp function.
  350.  
  351.                 The KCmpFnc function is passed two void pointers.  The first
  352.              parameter points  to the  data record  that has been previously
  353.              stored by  the management  routine.   The second parameter is a
  354.              key pointer  which  has  been  passed  into  the  'finding'  or
  355.              'adding' data  management function.   The KCmpFnc function must
  356.              return zero if the key field of the data record is equal to the
  357.              key parameter,  a negative  number if the key field of the data
  358.              record is less than the key parameter, and a positive number if
  359.              the key parameter is larger.
  360.  
  361.                 The second  (key) parameter of the KCmpFnc function probably
  362.              will not  point to  a record format identical to the one stored
  363.              by the data management class.  If you look at the Hadd function
  364.              you will  notice that  you must supply it with pointers both to
  365.              the data  record you are adding and to a key field contained in
  366.                                                                 contained   
  367.              that record.   This  key field  pointer is passed as the second
  368.              that                                                           
  369.              parameter to  the KCmpFnc  function.  I will attempt to explain
  370.              this in  the next  paragraph.   If  you  find  the  explanation
  371.              confusing just skip it.
  372.  
  373.                 The Salve  routines do  not store  key fields apart from the
  374.              rest of  the data  record.   The key field must be contained in
  375.              the data  record.   However, there  is a  definite advantage to
  376.              having you specify the key field for the KCmpFnc.  Refer to the
  377.              Hfind function.   When  you are searching for a specific record
  378.              you do  not want  to  create  an  empty  record  structure  and
  379.              populate the  key field.  You only want to pass in the key.  Of
  380.              course, you  could, by  design or  necessity, provide the basic
  381.              record pointer  as the  key field  pointer.   As  long  as  the
  382.              KCmpFnc knows  if the  second parameter  is a  complete  record
  383.              pointer or just a key field pointer (you couldn't mix and match
  384.              with a single handle), everything will work fine.
  385.  
  386.              HASHFNC
  387.  
  388.                 The  Hash  Table  class  requires  you  to  provide  a  hash
  389.              transformation  function.     This   function  is   passed  two
  390.              parameters.   The first parameter is a pointer to the key field
  391.              of the  data record you are putting into the table.  The second
  392.              parameter is  the maximum hash value allowable.  Typically, the
  393.              function will  transform the  key field into a positive integer
  394.              and then  'mod' that  integer by the second parameter.  As with
  395.              KCmpFnc, the  key field  parameter may  or may  not point  to a
  396.              record format identical to the one stored by the routine.
  397.  
  398.  
  399.  
  400.  
  401.  
  402.                                            - 6 -
  403.  
  404.  
  405.  
  406.  
  407.                                  Copyright Ron Albury 1988
  408.  
  409.              BEACHFNC
  410.  
  411.                 The final  user supplied  function is  only required  by the
  412.              Bfor_each utility.   The  Bfor_each  function  requires,  as  a
  413.              parameter, a  function that  takes two  parameters and  returns
  414.              void.   The first parameter to the user function is an unsigned
  415.              integer indicating the id of an element which is in a set.  The
  416.              second parameter  to the function is a user supplied pointer to
  417.              what ever  you want.   The  Bfor_each utility  calls  the  user
  418.              supplied function  for each  element in  the set, and passes in
  419.              the id of the element and the user supplied pointer.
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.                                            - 7 -
  469.  
  470.  
  471.  
  472.  
  473.                                  Copyright Ron Albury 1988
  474.  
  475.           BIT SET CLASS
  476.           BIT SET CLASS
  477.  
  478.                 The C  language is  generally richer  in types and operators
  479.              than Pascal.   One  area where Pascal has the upper hand is the
  480.              'SET'  type.     These   functions  provide  most  of  the  set
  481.              functionality found in Pascal.
  482.  
  483.                 A set  is a  collection of  objects of  the same  type.   An
  484.              example of  this is  the 'character set'.  Note that although a
  485.              set contains  multiple items,  each item  in the set is unique.
  486.              There are not two upper case A's in the set of characters.
  487.  
  488.                 A set  variable is a single variable used to represent a set
  489.              containing multiple  objects.   It is implemented here (as with
  490.              most Pascal  compilers) as  a string  of bits.  Each bit in the
  491.              set represents  one of  the objects  which could  belong to the
  492.              set.   If the  bit is  turned on it means that the object is in
  493.              the set.   If the bit is turned off it means that the object is
  494.              not in the set.
  495.  
  496.                 The objects  you add to the set must be an ordinal type (not
  497.              strings, not  floating point,  etc.).   You  can  use  the  set
  498.              functions to  manage sets  of characters,  sets of integers, or
  499.              sets of enumerated types.
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.                                            - 8 -
  536.  
  537.  
  538.  
  539.  
  540.                                  Copyright Ron Albury 1988
  541.  
  542.           FUNCTION Badd
  543.                    Badd
  544.  
  545.              PURPOSE
  546.  
  547.                 Adds an element to the indicated set.
  548.  
  549.              PARAMETERS
  550.  
  551.                 Root: (Input)
  552.                    The root of the set being accessed.
  553.  
  554.                 Bit_Id: (Input)
  555.                    The element to be placed into the set.
  556.  
  557.              RETURNS
  558.  
  559.                 Integer indicating  status of  the indicated  bit before the
  560.              element was added.
  561.                    0  = Bit was not set.
  562.                    !0 = Bit was already set.
  563.  
  564.              PROTOTYPE
  565.  
  566.                 int Badd
  567.                    (Broot root, void bit_id);
  568.  
  569.              DEBUG
  570.  
  571.                 The debug library (only) will report:
  572.                    1) Null root.
  573.                    2) Bit out of range.
  574.  
  575.              EXAMPLE
  576.  
  577.                 #include "salve.h"
  578.  
  579.                 main()
  580.                 {
  581.                    Broot  root;
  582.  
  583.                    /* open the bit set */
  584.                       :   :   :
  585.  
  586.                    /* turn on bit 74 */
  587.                    node = Badd (root, 74);
  588.  
  589.                    /* use the set */
  590.                       :   :   :
  591.  
  592.                    /* close the set */
  593.                 }
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.                                            - 9 -
  603.  
  604.  
  605.  
  606.  
  607.                                  Copyright Ron Albury 1988
  608.  
  609.           FUNCTION Bcard
  610.                    Bcard
  611.  
  612.              PURPOSE
  613.  
  614.                 Returns the  cardinality (number  of elements/number of bits
  615.              turned on) of the set.
  616.  
  617.              PARAMETERS
  618.  
  619.                 Root: (Input)
  620.                    The root of the set being accessed.
  621.  
  622.              RETURNS
  623.  
  624.                 Long integer  indicating number of elements currently in the
  625.              set.
  626.  
  627.              PROTOTYPE
  628.  
  629.                 long Bcard
  630.                    (Broot root);
  631.  
  632.              DEBUG
  633.  
  634.                 The debug library (only) will report:
  635.                    1) Null root.
  636.  
  637.              EXAMPLE
  638.  
  639.                 #include "salve.h"
  640.  
  641.                 main()
  642.                 {
  643.                    Broot  root;
  644.                    int    quan;
  645.  
  646.                    /* open the bit set */
  647.                       :   :   :
  648.  
  649.                    /* use the set */
  650.                       :   :   :
  651.  
  652.                    /* find out how many bits are on in the set */
  653.                    quan = Bcard (root);
  654.  
  655.                    /* close the set */
  656.                 }
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669.                                           - 10 -
  670.  
  671.  
  672.  
  673.  
  674.                                  Copyright Ron Albury 1988
  675.  
  676.           FUNCTION Bclose
  677.                    Bclose
  678.  
  679.              PURPOSE
  680.  
  681.                 Closes  a   previously  opened   bit  set.    There  are  NO
  682.                                                                           NO
  683.              restrictions requiring  you to  remove all  elements before the
  684.              set is closed.
  685.  
  686.              PARAMETERS
  687.  
  688.                 Root: (Input/Output)
  689.                    The root of the bit set being closed.
  690.  
  691.              RETURNS
  692.  
  693.                 Integer indicating status of the close.
  694.                    0 = Success.
  695.  
  696.              PROTOTYPE
  697.  
  698.                 int Bclose
  699.                    (Broot *root);
  700.  
  701.              DEBUG
  702.  
  703.                 Both libraries will report:
  704.                    1) Null root pointer.
  705.  
  706.              EXAMPLE
  707.  
  708.                 #include "salve.h"
  709.                 main()
  710.                 {
  711.                    int   status;
  712.                    Broot root;
  713.  
  714.                    /* open a 200 bit long set */
  715.                    status = Bopen (&root, 200);
  716.                       :   :   :
  717.  
  718.                    /* use the set */
  719.                       :   :   :
  720.  
  721.                    /* close the set */
  722.                    status = Bclose (&root);
  723.                 }
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734.  
  735.  
  736.  
  737.                                           - 11 -
  738.  
  739.  
  740.  
  741.  
  742.                                  Copyright Ron Albury 1988
  743.  
  744.           FUNCTION Bcomplement
  745.                    Bcomplement
  746.  
  747.              PURPOSE
  748.  
  749.                 Creates a  second bit  set which  is the  complement (all on
  750.              bits turned off, all off bits turned on) of the input set.
  751.  
  752.              PARAMETERS
  753.  
  754.                 Orig: (Input)
  755.                    The root of the set being duplicated.
  756.  
  757.                 Comp: (Output)
  758.                    The new set which is the complement of the input set.
  759.  
  760.              RETURNS
  761.  
  762.                 void.
  763.  
  764.              PROTOTYPE
  765.  
  766.                 void Bcomplement
  767.                    (Broot orig, Broot *comp);
  768.  
  769.              DEBUG
  770.  
  771.                 The debug library (only) will report:
  772.                    1) Null root.
  773.                    2) Illegal size for orig.
  774.                    3) Malloc failure.
  775.  
  776.              EXAMPLE
  777.  
  778.                 #include "salve.h"
  779.  
  780.                 main()
  781.                 {
  782.                    Broot root, flip;
  783.  
  784.                    /* open a set */
  785.                       :   :   :
  786.  
  787.                    /* load the set */
  788.                       :   :   :
  789.  
  790.                    /* create a set with all of the bits flipped */
  791.                    Bcomplement (root, &flip);
  792.  
  793.                    /* close the sets */
  794.                 }
  795.  
  796.  
  797.  
  798.  
  799.  
  800.  
  801.  
  802.  
  803.  
  804.                                           - 12 -
  805.  
  806.  
  807.  
  808.  
  809.                                  Copyright Ron Albury 1988
  810.  
  811.           FUNCTION Bdifference
  812.                    Bdifference
  813.  
  814.              PURPOSE
  815.  
  816.                 Creates a  third bit  set which  is the  difference (bitwise
  817.              exclusive or) of two input sets.
  818.  
  819.              PARAMETERS
  820.  
  821.                 Root1: (Input)
  822.                    The root of the first set being accessed.
  823.  
  824.                 Root2: (Input)
  825.                    The root of the second set being accessed.
  826.  
  827.                 Inter: (Output)
  828.                    The new  set which  is the difference of the two input
  829.                    sets.
  830.  
  831.              RETURNS
  832.  
  833.                 void.
  834.  
  835.              PROTOTYPE
  836.  
  837.                 void Bdifference
  838.                    (Broot root1, Broot root2, Broot *diff);
  839.  
  840.              DEBUG
  841.  
  842.                 The debug library (only) will report:
  843.                    1) Null root.
  844.                    2) Invalid size set.
  845.                    3) Sets not equal size.
  846.                    4) Malloc failure
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.  
  866.  
  867.  
  868.  
  869.  
  870.  
  871.                                           - 13 -
  872.  
  873.  
  874.  
  875.  
  876.                                  Copyright Ron Albury 1988
  877.  
  878.              EXAMPLE
  879.  
  880.                 #include "salve.h"
  881.  
  882.                 void userfunc (unsigned bit, void *ignore)
  883.                 {   printf ("bit %u is on\n", bit);   }
  884.  
  885.                 main()
  886.                 {
  887.                    Broot root1, root2, differ;
  888.  
  889.                    /* open set1 and set2 */
  890.                    /* load the sets */
  891.                       :   :   :
  892.  
  893.                    /* determine which bits are on in
  894.                       one set but not on in the other */
  895.                    Bdifference (root1, root2, &differ);
  896.  
  897.                    /* list all of the bits in the difference set */
  898.                    Bfor_each (differ, userfunc, NULL);
  899.  
  900.                    /* close the sets */
  901.                 }
  902.  
  903.  
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931.  
  932.  
  933.  
  934.  
  935.  
  936.  
  937.                                           - 14 -
  938.  
  939.  
  940.  
  941.  
  942.                                  Copyright Ron Albury 1988
  943.  
  944.           FUNCTION Bduplicate
  945.                    Bduplicate
  946.  
  947.              PURPOSE
  948.  
  949.                 Creates a second bit set which is the same as the input set.
  950.  
  951.              PARAMETERS
  952.  
  953.                 Orig: (Input)
  954.                    The root of the set being duplicated.
  955.  
  956.                 Copy: (Output)
  957.                    The new set which is a copy of the input set.
  958.  
  959.              RETURNS
  960.  
  961.                 void.
  962.  
  963.              PROTOTYPE
  964.  
  965.                 void Bduplicate
  966.                    (Broot orig, Broot *copy);
  967.  
  968.              DEBUG
  969.  
  970.                 The debug library (only) will report:
  971.                    1) Null root.
  972.                    2) Illegal size set.
  973.                    3) Malloc failure.
  974.  
  975.              EXAMPLE
  976.  
  977.                 #include "salve.h"
  978.  
  979.                 main()
  980.                 {
  981.                    Broot root, copy;
  982.  
  983.                    /* open a set */
  984.                       :   :   :
  985.  
  986.                    /* load the set */
  987.                       :   :   :
  988.  
  989.                    /* duplicate the set */
  990.                    Bdifference (root, ©);
  991.  
  992.                    /* close the sets */
  993.                 }
  994.  
  995.  
  996.  
  997.  
  998.  
  999.  
  1000.  
  1001.  
  1002.  
  1003.  
  1004.                                           - 15 -
  1005.  
  1006.  
  1007.  
  1008.  
  1009.                                  Copyright Ron Albury 1988
  1010.  
  1011.           FUNCTION Bequal
  1012.                    Bequal
  1013.  
  1014.              PURPOSE
  1015.  
  1016.                 Determines if  two bit  sets contain the same elements (have
  1017.              the same bits set).
  1018.  
  1019.              PARAMETERS
  1020.  
  1021.                 Root1: (Input)
  1022.                    The root of the first set being compared.
  1023.  
  1024.                 Root2: (Input)
  1025.                    The root of the second set being compared.
  1026.  
  1027.              RETURNS
  1028.  
  1029.                 An integer indicating the equality of the two sets:
  1030.                    < 0 : The first set had a lower bit set.
  1031.                    = 0 : The sets are equal.
  1032.                    > 0 : The second set had a lower bit set.
  1033.  
  1034.              PROTOTYPE
  1035.  
  1036.                 void Bequal
  1037.                    (Broot root1, Broot root2);
  1038.  
  1039.              DEBUG
  1040.  
  1041.                 The debug library (only) will report:
  1042.                    1) Null root.
  1043.                    2) Illegal size set.
  1044.                    3) Sets not equal size.
  1045.  
  1046.              EXAMPLE
  1047.  
  1048.                 #include "salve.h"
  1049.  
  1050.                 main()
  1051.                 {
  1052.                    Broot root1, root2;
  1053.                    int   status;
  1054.  
  1055.                    /* open set1 and set2 */
  1056.                       :   :   :
  1057.  
  1058.                    /* load the sets */
  1059.                       :   :   :
  1060.  
  1061.                    /* determine if the two sets have
  1062.                       the same bits turned on */
  1063.                    status = Bequal (root1, root2);
  1064.  
  1065.                    /* close the sets */
  1066.                 }
  1067.  
  1068.  
  1069.  
  1070.  
  1071.                                           - 16 -
  1072.  
  1073.  
  1074.  
  1075.  
  1076.                                  Copyright Ron Albury 1988
  1077.  
  1078.           FUNCTION Bfind_next
  1079.                    Bfind_next
  1080.  
  1081.              PURPOSE
  1082.  
  1083.                 Finds the  next element  (bit) present  (turned on)  in  the
  1084.              indicated set.   To  find the first bit set use a 'start' value
  1085.              of zero.
  1086.  
  1087.              PARAMETERS
  1088.  
  1089.                 Root: (Input)
  1090.                    The root of the set being accessed.
  1091.  
  1092.                 Start: (Input)
  1093.                    The first bit of the set to be tested.
  1094.  
  1095.                 Found: (Output)
  1096.                    The first  bit encountered in the set which was turned
  1097.                    on.  If no bits were found this parameter will contain
  1098.                    an unpredictable value.
  1099.  
  1100.              RETURNS
  1101.  
  1102.                 Integer indicating status of the search.
  1103.                    0 = Bit was found.
  1104.                    1 = No bits were found.
  1105.  
  1106.              PROTOTYPE
  1107.  
  1108.                 int Bfind_next
  1109.                    (Broot root, unsigned start, unsigned *found);
  1110.  
  1111.              DEBUG
  1112.  
  1113.                 The debug library (only) will report:
  1114.                    1) Null root.
  1115.                    2) Illegal size set.
  1116.                    3) Start out of range.
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131.  
  1132.  
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.                                           - 17 -
  1139.  
  1140.  
  1141.  
  1142.  
  1143.                                  Copyright Ron Albury 1988
  1144.  
  1145.              EXAMPLE
  1146.  
  1147.                 #include "salve.h"
  1148.  
  1149.                 main()
  1150.                 {
  1151.                    Broot    root;
  1152.                    unsigned bit;
  1153.                    int      status;
  1154.  
  1155.                    /* open the bit set */
  1156.                    /* use the set */
  1157.                       :   :   :
  1158.  
  1159.                    /* find the first 'on' bit in the set */
  1160.                    status = Bfind_next (root, 0, &bit);
  1161.  
  1162.                    /* find the next 'on' bit in the set */
  1163.                    status = Bfind_next (root, bit+1, &bit);
  1164.  
  1165.                    /* close the set */
  1166.                 }
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196.  
  1197.  
  1198.  
  1199.  
  1200.  
  1201.  
  1202.  
  1203.  
  1204.                                           - 18 -
  1205.  
  1206.  
  1207.  
  1208.  
  1209.                                  Copyright Ron Albury 1988
  1210.  
  1211.           FUNCTION Bfor_each
  1212.                    Bfor_each
  1213.  
  1214.              PURPOSE
  1215.  
  1216.                 Performs a  user define  function for  each element (bit) of
  1217.              the set which is present (turned on).
  1218.  
  1219.              PARAMETERS
  1220.  
  1221.                 Root: (Input)
  1222.                    The root of the set being accessed.
  1223.  
  1224.                 Func: (Input)
  1225.                    The function  to be  performed for each element of the
  1226.                    set.
  1227.  
  1228.                 UserArg: (Input)
  1229.                    The address  of a  user defined parameter to be passed
  1230.                    into the  function, along  with the  index of  the set
  1231.                    bit.
  1232.  
  1233.              RETURNS
  1234.  
  1235.                 Integer indicating number of elements currently in the set.
  1236.  
  1237.              PROTOTYPE
  1238.  
  1239.                 void Bfor_each
  1240.                    (Broot root, BEachFnc func, void *userarg);
  1241.  
  1242.              DEBUG
  1243.  
  1244.                 The debug library (only) will report:
  1245.                    1) Null root.
  1246.                    2) Illegal size set.
  1247.                    3) Null BEachFnc.
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.  
  1260.  
  1261.  
  1262.  
  1263.  
  1264.  
  1265.  
  1266.  
  1267.  
  1268.  
  1269.  
  1270.  
  1271.                                           - 19 -
  1272.  
  1273.  
  1274.  
  1275.  
  1276.                                  Copyright Ron Albury 1988
  1277.  
  1278.              EXAMPLE
  1279.  
  1280.                 #include "salve.h"
  1281.  
  1282.                 typedef struct
  1283.                 {
  1284.                    int a;
  1285.                    int b;
  1286.                    :   :
  1287.                 }
  1288.                    USER;
  1289.  
  1290.                 void userfunc (unsigned bit, USER *arg)
  1291.                 {
  1292.                    /* do something */
  1293.                 }
  1294.  
  1295.                 main()
  1296.                 {
  1297.                    Broot root;
  1298.                    USER  userarg;
  1299.  
  1300.                    /* open the bit set */
  1301.                       :   :   :
  1302.  
  1303.                    /* use the set */
  1304.                       :   :   :
  1305.  
  1306.                    /* call userfunc for each bit in the set */
  1307.                    set_value (&userarg);
  1308.                    Bfor_each (root, userfunc, &userarg);
  1309.  
  1310.                    /* close the set */
  1311.                 }
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  1320.  
  1321.  
  1322.  
  1323.  
  1324.  
  1325.  
  1326.  
  1327.  
  1328.  
  1329.  
  1330.  
  1331.  
  1332.  
  1333.  
  1334.  
  1335.  
  1336.  
  1337.                                           - 20 -
  1338.  
  1339.  
  1340.  
  1341.  
  1342.                                  Copyright Ron Albury 1988
  1343.  
  1344.           FUNCTION Bintersect
  1345.                    Bintersect
  1346.  
  1347.              PURPOSE
  1348.  
  1349.                 Creates a  third bit  set which is the intersection (bitwise
  1350.              and) of two input sets.
  1351.  
  1352.              PARAMETERS
  1353.  
  1354.                 Root1: (Input)
  1355.                    The root of the first set being accessed.
  1356.  
  1357.                 Root2: (Input)
  1358.                    The root of the second set being accessed.
  1359.  
  1360.                 Inter: (Output)
  1361.                    The new  set which is an intersection of the two input
  1362.                    sets.
  1363.  
  1364.              RETURNS
  1365.  
  1366.                 void.
  1367.  
  1368.              PROTOTYPE
  1369.  
  1370.                 int Bintersect
  1371.                    (Broot root1, Broot root2, Broot *inter);
  1372.  
  1373.              DEBUG
  1374.  
  1375.                 The debug library (only) will report:
  1376.                    1) Null root.
  1377.                    2) Malloc failure.
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401.  
  1402.  
  1403.  
  1404.                                           - 21 -
  1405.  
  1406.  
  1407.  
  1408.  
  1409.                                  Copyright Ron Albury 1988
  1410.  
  1411.              EXAMPLE
  1412.  
  1413.                 #include "salve.h"
  1414.  
  1415.                 void userfunc (unsigned bit, void *ignore)
  1416.                 {
  1417.                    printf ("bit %u is on\n", bit);
  1418.                 }
  1419.  
  1420.                 main()
  1421.                 {
  1422.                    Broot root1, root2, inter;
  1423.  
  1424.                    /* open set1 and set2 */
  1425.                    /* load the sets */
  1426.                       :   :   :
  1427.  
  1428.                    /* determine which bits are on in both sets */
  1429.                    Bintersect (root1, root2, &inter);
  1430.  
  1431.                    /* list all of the bits in the intersection set */
  1432.                    Bfor_each (inter, userfunc, NULL);
  1433.  
  1434.                    /* close the sets */
  1435.                 }
  1436.  
  1437.  
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  1457.  
  1458.  
  1459.  
  1460.  
  1461.  
  1462.  
  1463.  
  1464.  
  1465.  
  1466.  
  1467.  
  1468.  
  1469.  
  1470.                                           - 22 -
  1471.  
  1472.  
  1473.  
  1474.  
  1475.                                  Copyright Ron Albury 1988
  1476.  
  1477.           FUNCTION Bopen
  1478.                    Bopen
  1479.  
  1480.              PURPOSE
  1481.  
  1482.                 Opens  an   unrestricted  bit   set  and  creates  the  data
  1483.              structures necessary  for its  management.   As with Lopen, you
  1484.              must call  this function  for each  bit set  to be  used.  This
  1485.              function is  required before any other of the bit set functions
  1486.              can be performed.
  1487.  
  1488.                 These routines  are  comparable  to  Pascal  sets,  and  are
  1489.              intended for  use when  sets with more than 32 elements must be
  1490.              managed.   For sets  with 32  or  fewer  elements  it  is  more
  1491.              efficient to  use bit  oriented operations  on long  or integer
  1492.              variables.
  1493.  
  1494.              PARAMETERS
  1495.  
  1496.                 Root: (Output)
  1497.                    The root  (or handle)  of the  bit set  being  opened.
  1498.                    Referenced by all other bit set functions.
  1499.  
  1500.                 Size:  (Input)
  1501.                    The number of bits to manage in this set.  This number
  1502.                    can be  as small  as  two,  or  as  large  as  can  be
  1503.                    accommodated by  an unsigned  value.  If you are using
  1504.                    the set  to manage  an enumerated type you may pass in
  1505.                    the largest  (last) element of the enumerated type for
  1506.                    this parameter.
  1507.  
  1508.              RETURNS
  1509.  
  1510.                 Integer indicating status of the open.
  1511.                    0 = Success.
  1512.  
  1513.              PROTOTYPE
  1514.  
  1515.                 int Bopen
  1516.                    (Broot *root, unsigned size);
  1517.  
  1518.              DEBUG
  1519.  
  1520.                 Both libraries will report:
  1521.                    1) Null root pointer.
  1522.                    2) Malloc failure.
  1523.  
  1524.  
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530.  
  1531.  
  1532.  
  1533.  
  1534.  
  1535.  
  1536.  
  1537.                                           - 23 -
  1538.  
  1539.  
  1540.  
  1541.  
  1542.                                  Copyright Ron Albury 1988
  1543.  
  1544.              EXAMPLE
  1545.  
  1546.                 #include "salve.h"
  1547.  
  1548.                 typedef enum
  1549.                 {
  1550.                     Sunday, Monday, Tuesday, Wednesday,
  1551.                     Thursday, Friday, Saturday
  1552.                 }
  1553.                     DAYS_OF_WEEK;
  1554.  
  1555.                 
  1556.                 main()
  1557.                 {
  1558.                    int   status;
  1559.                    Broot root_int, root_days;
  1560.  
  1561.                    /* open a 200 bit long set */
  1562.                    status = Bopen (&root_int, 200);
  1563.                       :   :   :
  1564.  
  1565.                    /* open a weekday set */
  1566.                    status = Bopen (&root_days, Saturday);
  1567.                       :   :   :
  1568.                 }
  1569.  
  1570.  
  1571.  
  1572.  
  1573.  
  1574.  
  1575.  
  1576.  
  1577.  
  1578.  
  1579.  
  1580.  
  1581.  
  1582.  
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590.  
  1591.  
  1592.  
  1593.  
  1594.  
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.  
  1601.  
  1602.  
  1603.                                           - 24 -
  1604.  
  1605.  
  1606.  
  1607.  
  1608.                                  Copyright Ron Albury 1988
  1609.  
  1610.           FUNCTION Bremove
  1611.                    Bremove
  1612.  
  1613.              PURPOSE
  1614.  
  1615.                 Removes an element from the indicated set.
  1616.  
  1617.              PARAMETERS
  1618.  
  1619.                 Root: (Input)
  1620.                    The root of the set being accessed.
  1621.  
  1622.                 Bit_Id: (Input)
  1623.                    The element to remove from the set.
  1624.  
  1625.              RETURNS
  1626.  
  1627.                 Integer indicating status of the removal.
  1628.                    0 = Success.
  1629.  
  1630.              PROTOTYPE
  1631.  
  1632.                 int Bremove
  1633.                    (Broot root, unsigned bit_id);
  1634.  
  1635.              DEBUG
  1636.  
  1637.                 The debug library (only) will report:
  1638.                    1) Null root.
  1639.                    2) Invalid bit id.
  1640.  
  1641.              EXAMPLE
  1642.  
  1643.                 #include "salve.h"
  1644.  
  1645.                 main()
  1646.                 {
  1647.                    Broot  root;
  1648.  
  1649.                    /* open the bit set */
  1650.                       :   :   :
  1651.  
  1652.                    /* turn on bit 74 */
  1653.                    node = Badd (root, 74);
  1654.  
  1655.                    /* use the set */
  1656.                       :   :   :
  1657.  
  1658.                    /* turn off bit 74 */
  1659.                    node = Bremove (root, 74);
  1660.  
  1661.                    /* close the set */
  1662.                 }
  1663.  
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.                                           - 25 -
  1671.  
  1672.  
  1673.  
  1674.  
  1675.                                  Copyright Ron Albury 1988
  1676.  
  1677.           FUNCTION Btest_in
  1678.                    Btest_in
  1679.  
  1680.              PURPOSE
  1681.  
  1682.                 Tests if  a specific  element (bit)  is in the indicated bit
  1683.              set.
  1684.  
  1685.              PARAMETERS
  1686.  
  1687.                 Root: (Input)
  1688.                    The root of the set being accessed.
  1689.  
  1690.                 Bit_Id: (Input)
  1691.                    The bit of the set to be tested.
  1692.  
  1693.              RETURNS
  1694.  
  1695.                 Integer indicating status of the bit.
  1696.                    0  = Bit is not set.
  1697.                    !0 = Bit is set.
  1698.  
  1699.              PROTOTYPE
  1700.  
  1701.                 int Btest_in
  1702.                    (Broot root, unsigned bit_id);
  1703.  
  1704.              DEBUG
  1705.  
  1706.                 The debug library (only) will report:
  1707.                    1) Null root.
  1708.                    2) Invalid bit id.
  1709.  
  1710.              EXAMPLE
  1711.  
  1712.                 #include "salve.h"
  1713.  
  1714.                 main()
  1715.                 {
  1716.                    Broot  root;
  1717.                    int    quan;
  1718.  
  1719.                    /* open the bit set */
  1720.                       :   :   :
  1721.  
  1722.                    /* use the set */
  1723.                       :   :   :
  1724.  
  1725.                    /* test if bit 48 is in the set */
  1726.                    quan = Btest_in (root, 48);
  1727.  
  1728.                    /* close the set */
  1729.                 }
  1730.  
  1731.  
  1732.  
  1733.  
  1734.  
  1735.  
  1736.  
  1737.                                           - 26 -
  1738.  
  1739.  
  1740.  
  1741.  
  1742.                                  Copyright Ron Albury 1988
  1743.  
  1744.           FUNCTION Btoggle
  1745.                    Btoggle
  1746.  
  1747.              PURPOSE
  1748.  
  1749.                 Toggles an element (xor's it) in the indicated set.
  1750.  
  1751.              PARAMETERS
  1752.  
  1753.                 Root: (Input)
  1754.                    The root of the set being accessed.
  1755.  
  1756.                 Bit_Id: (Input)
  1757.                    The element in the set to toggle.
  1758.  
  1759.              RETURNS
  1760.  
  1761.                 Integer indicating status of the bit before the toggle.
  1762.                    0  = Bit was not set.
  1763.                    !0 = Bit was set.
  1764.  
  1765.              PROTOTYPE
  1766.  
  1767.                 int Btoggle
  1768.                    (Broot root, void bit_id);
  1769.  
  1770.              DEBUG
  1771.  
  1772.                 The debug library (only) will report:
  1773.                    1) Null root.
  1774.                    2) Invalid bit id.
  1775.  
  1776.              EXAMPLE
  1777.  
  1778.                 #include "salve.h"
  1779.  
  1780.                 main()
  1781.                 {
  1782.                    Broot  root;
  1783.  
  1784.                    /* open the bit set */
  1785.                       :   :   :
  1786.  
  1787.                    /* toggle bit 45 */
  1788.                    node = Btoggle (root, 45);
  1789.  
  1790.                    /* use the set */
  1791.                       :   :   :
  1792.  
  1793.                    /* close the set */
  1794.                 }
  1795.  
  1796.  
  1797.  
  1798.  
  1799.  
  1800.  
  1801.  
  1802.  
  1803.  
  1804.                                           - 27 -
  1805.  
  1806.  
  1807.  
  1808.  
  1809.                                  Copyright Ron Albury 1988
  1810.  
  1811.           FUNCTION Bunion
  1812.                    Bunion
  1813.  
  1814.              PURPOSE
  1815.  
  1816.                 Creates  a  third  bit  set  which  is  the  union  (bitwise
  1817.              inclusive or) of two input sets.
  1818.  
  1819.              PARAMETERS
  1820.  
  1821.                 Root1: (Input)
  1822.                    The root of the first set being accessed.
  1823.  
  1824.                 Root2: (Input)
  1825.                    The root of the second set being accessed.
  1826.  
  1827.                 Union: (Output)
  1828.                    The new set which is a union of the two input sets.
  1829.  
  1830.              RETURNS
  1831.  
  1832.                 void.
  1833.  
  1834.              PROTOTYPE
  1835.  
  1836.                 void Bunion
  1837.                    (Broot root1, Broot root2, Broot *union);
  1838.  
  1839.              DEBUG
  1840.  
  1841.                 The debug library (only) will report:
  1842.                    1) Null root.
  1843.                    2) Sets not equal size.
  1844.                    3) Malloc failure.
  1845.  
  1846.  
  1847.  
  1848.  
  1849.  
  1850.  
  1851.  
  1852.  
  1853.  
  1854.  
  1855.  
  1856.  
  1857.  
  1858.  
  1859.  
  1860.  
  1861.  
  1862.  
  1863.  
  1864.  
  1865.  
  1866.  
  1867.  
  1868.  
  1869.  
  1870.  
  1871.                                           - 28 -
  1872.  
  1873.  
  1874.  
  1875.  
  1876.                                  Copyright Ron Albury 1988
  1877.  
  1878.              EXAMPLE
  1879.  
  1880.                 #include "salve.h"
  1881.  
  1882.                 void userfunc (unsigned bit, void *ignore)
  1883.                 {
  1884.                    printf ("bit %u is on\n", bit);
  1885.                 }
  1886.  
  1887.                 main()
  1888.                 {
  1889.                    Broot root1, root2, uni;
  1890.  
  1891.                    /* open set1 and set2 */
  1892.                    /* load the sets */
  1893.                       :   :   :
  1894.  
  1895.                    /* determine which bits are on in either set */
  1896.                    Bunion (root1, root2, &uni);
  1897.  
  1898.                    /* list all of the bits in the union set */
  1899.                    Bfor_each (uni, userfunc, NULL);
  1900.  
  1901.                    /* close the sets */
  1902.                 }
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.  
  1910.  
  1911.  
  1912.  
  1913.  
  1914.  
  1915.  
  1916.  
  1917.  
  1918.  
  1919.  
  1920.  
  1921.  
  1922.  
  1923.  
  1924.  
  1925.  
  1926.  
  1927.  
  1928.  
  1929.  
  1930.  
  1931.  
  1932.  
  1933.  
  1934.  
  1935.  
  1936.  
  1937.                                           - 29 -
  1938.  
  1939.  
  1940.  
  1941.  
  1942.                                  Copyright Ron Albury 1988
  1943.  
  1944.           HASH TABLE CLASS
  1945.           HASH TABLE CLASS
  1946.  
  1947.                 Hashing is  the technique  of transforming  a key value from
  1948.              one  format   (such  as   a  character  string)  into  another,
  1949.              equivalent format  (an integer)  that is  easier to  use as  an
  1950.              index.
  1951.  
  1952.                 A good  transforming function  takes the  original keys  and
  1953.              returns  indices   which  are   evenly   distributed   over   a
  1954.                                              evenly                         
  1955.              predetermined range.   There  are  a  number  of  factors  that
  1956.              determine how  evenly the  indices are  distributed.    A  good
  1957.              transforming function  must take  into account the type of data
  1958.              being hashed,  and even  the choice  of the  maximum  allowable
  1959.              index value.   Using  a prime number for the maximum value will
  1960.              (for some reason) provide better distribution.
  1961.  
  1962.                 Ideally, given  unique keys the transformation function will
  1963.              return unique  indices.   However, we  do not  live in an ideal
  1964.              world.   The hash  table  functions  make  provisions  for  the
  1965.              transform function  returning the  same index  for  two  unique
  1966.              keys.   This collision  handling is  taken care  of by a backup
  1967.              comparison on the original key.
  1968.  
  1969.                 A typical  approach for transforming character strings is to
  1970.              add up  the values  of the  characters and then mod them by the
  1971.              maximum allowable  value.   There are  algorithms to  transform
  1972.              strings based on phonetics, and simpler (and faster transforms)
  1973.              based on  just a  few selected  characters from  the  character
  1974.              string (e.g the sum of the first character, the last character,
  1975.              and the  length of  the string).   Hashing  can be performed on
  1976.              data types  other than  character strings, but that is the most
  1977.              typical use.
  1978.  
  1979.                 Hash  tables   are  frequently  used  to  index  other  data
  1980.              structures.   A typical  application would  be to have a linked
  1981.              list of  records, ordered  on a  First In  First  Out  or  Most
  1982.              Recently Used  basis, which has a hash index to allow key based
  1983.              searching.   There is,  however, no  restriction on  the use of
  1984.              these hash  table functions.  They can be use to directly store
  1985.              pointers  to   large  records,   or  to   index  other  storage
  1986.              techniques.
  1987.  
  1988.                 One possible  drawback to  hash tables  is that  you can not
  1989.              easily access the data items in the hash table except by direct
  1990.              look-up based  on the  key.  Hash tables generally provide much
  1991.              faster access  than sequential  search or  even  binary  trees.
  1992.              However, if you need an additional searching technique you must
  1993.              either use  a different  class of  data management to store the
  1994.              data (such as a tree) or combine hashing with another class.
  1995.  
  1996.  
  1997.  
  1998.  
  1999.  
  2000.  
  2001.  
  2002.  
  2003.  
  2004.  
  2005.                                           - 30 -
  2006.  
  2007.  
  2008.  
  2009.  
  2010.                                  Copyright Ron Albury 1988
  2011.  
  2012.           FUNCTION Hadd
  2013.                    Hadd
  2014.  
  2015.              PURPOSE
  2016.  
  2017.                 Adds a  data element  to the  appropriate slot  of the  hash
  2018.              table.  Duplicate entries are not permitted.
  2019.  
  2020.              PARAMETERS
  2021.  
  2022.                 Root: (Input)
  2023.                    The root of the table being accessed.
  2024.  
  2025.                 Data: (Input)
  2026.                    The data element to be placed into the table.
  2027.  
  2028.                 Key:  (Input)
  2029.                    The key  field to  pass to  the compare  function  for
  2030.                    determining table  location.   This  field  may  be  a
  2031.                    pointer to  a record  of the  same type  as  the  data
  2032.                    element,  or  it  may  be  a  pointer  to  some  other
  2033.                    structure (e.g just a field of the data element record
  2034.                    structure).
  2035.  
  2036.              RETURNS
  2037.  
  2038.                 An Hnode pointer
  2039.                    Success: Hash node of the added element.
  2040.                    Failure: NULL (duplicate entry found).
  2041.  
  2042.                 Hash node of the added element.
  2043.  
  2044.              PROTOTYPE
  2045.  
  2046.                 Hnode Hadd
  2047.                    (Hroot hroot, void *data, void *key);
  2048.  
  2049.              DEBUG
  2050.  
  2051.                 The debug library (only) will report:
  2052.                    1) Null root.
  2053.                    2) Null data.
  2054.                    3) Null key.
  2055.                    4) Malloc failure.
  2056.  
  2057.  
  2058.  
  2059.  
  2060.  
  2061.  
  2062.  
  2063.  
  2064.  
  2065.  
  2066.  
  2067.  
  2068.  
  2069.  
  2070.  
  2071.  
  2072.                                           - 31 -
  2073.  
  2074.  
  2075.  
  2076.  
  2077.                                  Copyright Ron Albury 1988
  2078.  
  2079.              EXAMPLE
  2080.  
  2081.                 #include "salve.h"
  2082.  
  2083.                 main()
  2084.                 {
  2085.                    struct UserRec *u;
  2086.                    char   key[32];
  2087.                    Hnode  node;
  2088.                    Hroot  root;
  2089.  
  2090.                    /* open the hash table */
  2091.                       :   :   :
  2092.  
  2093.                    /* create a new data element for the table */
  2094.                    u = malloc(sizeof(struct UserRec));
  2095.  
  2096.                    /* assign values to the new data element */
  2097.                    gets (key);
  2098.                    assign_values(u, key);
  2099.  
  2100.                    /* add the new data to the table */
  2101.                    node = Hadd (root, u, key);
  2102.  
  2103.                    /* use the table */
  2104.                       :   :   :
  2105.  
  2106.                    /* close the table */
  2107.  
  2108.                 }
  2109.  
  2110.  
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116.  
  2117.  
  2118.  
  2119.  
  2120.  
  2121.  
  2122.  
  2123.  
  2124.  
  2125.  
  2126.  
  2127.  
  2128.  
  2129.  
  2130.  
  2131.  
  2132.  
  2133.  
  2134.  
  2135.  
  2136.  
  2137.  
  2138.                                           - 32 -
  2139.  
  2140.  
  2141.  
  2142.  
  2143.                                  Copyright Ron Albury 1988
  2144.  
  2145.           FUNCTION Hcard
  2146.                    Hcard
  2147.  
  2148.              PURPOSE
  2149.  
  2150.                 Returns the cardinality (number of elements) of the table.
  2151.  
  2152.              PARAMETERS
  2153.  
  2154.                 Root: (Input)
  2155.                    The root of the table being accessed.
  2156.  
  2157.              RETURNS
  2158.  
  2159.                 Long integer  indicating number of elements currently in the
  2160.              table.
  2161.  
  2162.              PROTOTYPE
  2163.  
  2164.                 long Hcard
  2165.                    (Hroot root);
  2166.  
  2167.              DEBUG
  2168.  
  2169.                 The debug library (only) will report:
  2170.                    1) Null root.
  2171.  
  2172.              EXAMPLE
  2173.  
  2174.                 #include "salve.h"
  2175.  
  2176.                 main()
  2177.                 {
  2178.                    Hroot  root;
  2179.                    int    quan;
  2180.  
  2181.                    /* open the hash table */
  2182.                       :   :   :
  2183.  
  2184.                    /* use the table */
  2185.                       :   :   :
  2186.  
  2187.                    /* find out how elements are in the table */
  2188.                    quan = Hcard (root);
  2189.  
  2190.                    /* close the table */
  2191.                 }
  2192.  
  2193.  
  2194.  
  2195.  
  2196.  
  2197.  
  2198.  
  2199.  
  2200.  
  2201.  
  2202.  
  2203.  
  2204.  
  2205.                                           - 33 -
  2206.  
  2207.  
  2208.  
  2209.  
  2210.                                  Copyright Ron Albury 1988
  2211.  
  2212.           FUNCTION Hclose
  2213.                    Hclose
  2214.  
  2215.              PURPOSE
  2216.  
  2217.                 Closes a  previously opened  hash table.   All elements must
  2218.              have been removed from the table before the table is closed.
  2219.  
  2220.              PARAMETERS
  2221.  
  2222.                 Root: (Input/Output)
  2223.                    The root of the table being closed.
  2224.  
  2225.              RETURNS
  2226.  
  2227.                 Integer indicating status of close.
  2228.                    0 = Success.
  2229.                    1 =  Elements were left in the table.  Remove them and
  2230.                        try again.
  2231.  
  2232.              PROTOTYPE
  2233.  
  2234.                 int Hclose
  2235.                    (Hroot *root);
  2236.  
  2237.              DEBUG
  2238.  
  2239.                 Both libraries will report:
  2240.                    1) Null root pointer.
  2241.  
  2242.              EXAMPLE
  2243.  
  2244.                 #include "salve.h"
  2245.  
  2246.                 main()
  2247.                 {
  2248.                    int   status;
  2249.                    Hroot root;
  2250.  
  2251.                    /* open the hash table */
  2252.                       :   :   :
  2253.                    /* use the hash table */
  2254.                       :   :   :
  2255.                    status = Hclose (&root);
  2256.                 }
  2257.  
  2258.  
  2259.  
  2260.  
  2261.  
  2262.  
  2263.  
  2264.  
  2265.  
  2266.  
  2267.  
  2268.  
  2269.  
  2270.  
  2271.  
  2272.                                           - 34 -
  2273.  
  2274.  
  2275.  
  2276.  
  2277.                                  Copyright Ron Albury 1988
  2278.  
  2279.           FUNCTION Hfind
  2280.                    Hfind
  2281.  
  2282.              PURPOSE
  2283.  
  2284.                 Finds a data element in the indicated hash table.
  2285.  
  2286.              PARAMETERS
  2287.  
  2288.                 Root:  (Input)
  2289.                    The root of the table being accessed.
  2290.  
  2291.                 Key:   (Input)
  2292.                    The  key  field  to  pass  to  the  compare  and  hash
  2293.                    functions for selecting table element.
  2294.  
  2295.                 Found: (Output)
  2296.                    The data element in the table which matches the key.
  2297.  
  2298.              RETURNS
  2299.  
  2300.                 An Hnode pointer
  2301.                    Success: Hash node of the found element.
  2302.                    Failure: NULL (node not found).
  2303.  
  2304.              PROTOTYPE
  2305.  
  2306.                 Hnode Hfind
  2307.                    (Hroot root, void *key, void *found);
  2308.  
  2309.              DEBUG
  2310.  
  2311.                 The debug library (only) will report:
  2312.                    1) Null root.
  2313.                    2) Null key.
  2314.                    3) Found parameter null.
  2315.  
  2316.  
  2317.  
  2318.  
  2319.  
  2320.  
  2321.  
  2322.  
  2323.  
  2324.  
  2325.  
  2326.  
  2327.  
  2328.  
  2329.  
  2330.  
  2331.  
  2332.  
  2333.  
  2334.  
  2335.  
  2336.  
  2337.  
  2338.  
  2339.                                           - 35 -
  2340.  
  2341.  
  2342.  
  2343.  
  2344.                                  Copyright Ron Albury 1988
  2345.  
  2346.              EXAMPLE
  2347.  
  2348.                 #include "salve.h"
  2349.  
  2350.                 main()
  2351.                 {
  2352.                    struct UserRec *u;
  2353.                    char   key[32];
  2354.                    Hnode  node;
  2355.                    Hroot  root;
  2356.  
  2357.                    /* open the hash table */
  2358.                    /* add data elements to the table */
  2359.                       :   :   :
  2360.  
  2361.                    /* find the node with a given key */
  2362.                    node = Hfind (root, key, &found);
  2363.  
  2364.                    /* use the table */
  2365.                       :   :   :
  2366.  
  2367.                    /* close the table */
  2368.  
  2369.                 }
  2370.  
  2371.  
  2372.  
  2373.  
  2374.  
  2375.  
  2376.  
  2377.  
  2378.  
  2379.  
  2380.  
  2381.  
  2382.  
  2383.  
  2384.  
  2385.  
  2386.  
  2387.  
  2388.  
  2389.  
  2390.  
  2391.  
  2392.  
  2393.  
  2394.  
  2395.  
  2396.  
  2397.  
  2398.  
  2399.  
  2400.  
  2401.  
  2402.  
  2403.  
  2404.  
  2405.                                           - 36 -
  2406.  
  2407.  
  2408.  
  2409.  
  2410.                                  Copyright Ron Albury 1988
  2411.  
  2412.           FUNCTION Hfind_node
  2413.                    Hfind_node
  2414.  
  2415.              PURPOSE
  2416.  
  2417.                 Finds the  data element  associated with  a hash table node.
  2418.              This function  is useful if you store the nodes in another data
  2419.              management structure (such as a tree).
  2420.  
  2421.              PARAMETERS
  2422.  
  2423.                 Node:  (Input)
  2424.                    The  hash  table  node  to  be  used  in  finding  the
  2425.                    requested data.
  2426.  
  2427.                 Found: (Output)
  2428.                    The data element located at that node.
  2429.  
  2430.              RETURNS
  2431.  
  2432.                 void.
  2433.  
  2434.              PROTOTYPE
  2435.  
  2436.                 void Hfind_node
  2437.                    (Hnode node, void **found);
  2438.  
  2439.              DEBUG
  2440.  
  2441.                 The debug library (only) will report:
  2442.                    1) Null node.
  2443.                    2) Found parameter null.
  2444.  
  2445.  
  2446.  
  2447.  
  2448.  
  2449.  
  2450.  
  2451.  
  2452.  
  2453.  
  2454.  
  2455.  
  2456.  
  2457.  
  2458.  
  2459.  
  2460.  
  2461.  
  2462.  
  2463.  
  2464.  
  2465.  
  2466.  
  2467.  
  2468.  
  2469.  
  2470.  
  2471.  
  2472.                                           - 37 -
  2473.  
  2474.  
  2475.  
  2476.  
  2477.                                  Copyright Ron Albury 1988
  2478.  
  2479.              EXAMPLE
  2480.  
  2481.                 #include "salve.h"
  2482.  
  2483.                 main()
  2484.                 {
  2485.                    struct UserRec *u;
  2486.                    Hnode  node;
  2487.                    Hroot  root;
  2488.  
  2489.                    /* open the hash table */
  2490.                       :   :   :
  2491.                    /* add records to the table */
  2492.                       :   :   :
  2493.                    /* cross reference them in a tree */
  2494.                       :   :   :
  2495.  
  2496.                    /* find a node through the tree *
  2497.                       :   :   :
  2498.  
  2499.                    /* get the data associated with it */
  2500.                    Hfind_node (node, &u);
  2501.  
  2502.                    /* delete the node from the tree and the table */
  2503.                       :   :   :
  2504.  
  2505.                    /* close the table */
  2506.                 }
  2507.  
  2508.  
  2509.  
  2510.  
  2511.  
  2512.  
  2513.  
  2514.  
  2515.  
  2516.  
  2517.  
  2518.  
  2519.  
  2520.  
  2521.  
  2522.  
  2523.  
  2524.  
  2525.  
  2526.  
  2527.  
  2528.  
  2529.  
  2530.  
  2531.  
  2532.  
  2533.  
  2534.  
  2535.  
  2536.  
  2537.  
  2538.                                           - 38 -
  2539.  
  2540.  
  2541.  
  2542.  
  2543.                                  Copyright Ron Albury 1988
  2544.  
  2545.           FUNCTION Hopen
  2546.                    Hopen
  2547.  
  2548.              PURPOSE
  2549.  
  2550.                 Opens a hash table and creates the data structures necessary
  2551.              for its management.  As with Lopen, you must call this function
  2552.              for each  hash table  to be  used.   This function  is required
  2553.              before any  other of the hash functions can be performed on the
  2554.              hash table.  Hash tables can be used to index a linked list (in
  2555.              this case  the data  item stored in the table is the list node)
  2556.              or to store data directly.
  2557.  
  2558.              PARAMETERS
  2559.  
  2560.                 Root: (Output)
  2561.                    The root  (or handle)  of the hash table being opened.
  2562.                    Referenced by all other hash functions.
  2563.  
  2564.                 Quan: (Input)
  2565.                    The size  of the hash table to create.  This should be
  2566.                    approximately 1.5  times  the  estimated  quantity  of
  2567.                    elements to  be stored  in the  table (+ or - 25%. Too
  2568.                    few slows  down/too many takes up space).  Performance
  2569.                    may be  improved slightly if you choose a prime number
  2570.                    for this value.
  2571.  
  2572.                 Comp: (Input)
  2573.                    The comparison  function to  be used  with this  list.
  2574.                    This function  should return  0 for  equal, less  than
  2575.                    zero if  the data  is less  than the  key, and greater
  2576.                    than zero if the data is greater than the key.
  2577.  
  2578.                 Hash: (Input)
  2579.                    The hash  function for  this table.  Given a key value
  2580.                    and a  modulus, this function should return an integer
  2581.                    value in the range of 0 to modulous-1.
  2582.  
  2583.              RETURNS
  2584.  
  2585.                 Integer indicating status of the open.
  2586.                    0 = Success.
  2587.  
  2588.              PROTOTYPE
  2589.  
  2590.                 int Hopen
  2591.                    (Hroot *root, unsigned quan, KCmpFnc comp, HashFnc
  2592.                    hash);
  2593.  
  2594.  
  2595.  
  2596.  
  2597.  
  2598.  
  2599.  
  2600.  
  2601.  
  2602.  
  2603.  
  2604.  
  2605.                                           - 39 -
  2606.  
  2607.  
  2608.  
  2609.  
  2610.                                  Copyright Ron Albury 1988
  2611.  
  2612.              DEBUG
  2613.  
  2614.                 Both libraries will report:
  2615.                    1) Null root pointer.
  2616.                    2) Invalid quanity.
  2617.                    3) Null compare function.
  2618.                    4) Null hash function.
  2619.                    5) Malloc failure.
  2620.  
  2621.              EXAMPLE
  2622.  
  2623.                 #include "salve.h"
  2624.  
  2625.                 int compare (void *data, void *key)
  2626.                 {
  2627.                   /* compare the data with the key */
  2628.                    :   :   :
  2629.                 }
  2630.  
  2631.                 int hash (void *key, unsigned mod)
  2632.                 {
  2633.                   /* calculate a hash value based on the key */
  2634.                    :   :   :
  2635.                 }
  2636.  
  2637.                 main()
  2638.                 {
  2639.                    int   status;
  2640.                    Hroot root;
  2641.  
  2642.                    status = Hopen (&root, 101, compare, hash);
  2643.                       :   :   :
  2644.                 }
  2645.  
  2646.  
  2647.  
  2648.  
  2649.  
  2650.  
  2651.  
  2652.  
  2653.  
  2654.  
  2655.  
  2656.  
  2657.  
  2658.  
  2659.  
  2660.  
  2661.  
  2662.  
  2663.  
  2664.  
  2665.  
  2666.  
  2667.  
  2668.  
  2669.  
  2670.  
  2671.                                           - 40 -
  2672.  
  2673.  
  2674.  
  2675.  
  2676.                                  Copyright Ron Albury 1988
  2677.  
  2678.           FUNCTION Hremove
  2679.                    Hremove
  2680.  
  2681.              PURPOSE
  2682.  
  2683.                 Removes a  node and  data element  from the  indicated  hash
  2684.              table.
  2685.  
  2686.              PARAMETERS
  2687.  
  2688.                 Root: (Input)
  2689.                    The root of the table being accessed.
  2690.  
  2691.                 Drop_Node: (Input)
  2692.                    The hash node of the element to remove.
  2693.  
  2694.              RETURNS
  2695.  
  2696.                 Integer indicating status of the removal.
  2697.                    0 = Success.
  2698.                    1 = Corrupted memory, or node not part of table.
  2699.  
  2700.              PROTOTYPE
  2701.  
  2702.                 int Hremove
  2703.                    (Hroot root, Hnode drop_node);
  2704.  
  2705.              DEBUG
  2706.  
  2707.                 The debug library (only) will report:
  2708.                    1) Null root.
  2709.                    2) Null drop node.
  2710.                    3) Node consistency tests.
  2711.  
  2712.  
  2713.  
  2714.  
  2715.  
  2716.  
  2717.  
  2718.  
  2719.  
  2720.  
  2721.  
  2722.  
  2723.  
  2724.  
  2725.  
  2726.  
  2727.  
  2728.  
  2729.  
  2730.  
  2731.  
  2732.  
  2733.  
  2734.  
  2735.  
  2736.  
  2737.  
  2738.                                           - 41 -
  2739.  
  2740.  
  2741.  
  2742.  
  2743.                                  Copyright Ron Albury 1988
  2744.  
  2745.              EXAMPLE
  2746.  
  2747.                 #include "salve.h"
  2748.  
  2749.                 main()
  2750.                 {
  2751.                    struct UserRec *u;
  2752.                    char   key[32];
  2753.                    int    status;
  2754.                    Hnode  node;
  2755.                    Hroot  root;
  2756.  
  2757.                    /* open the hash table */
  2758.                    /* add data elements to the table */
  2759.                       :   :   :
  2760.  
  2761.                    /* find the node with a given key */
  2762.                    node = Hfind (root, key, &u);
  2763.  
  2764.                    /* remove that node */
  2765.                    status = Hremove (root, node);
  2766.  
  2767.                    /* use the table */
  2768.                       :   :   :
  2769.  
  2770.                    /* close the table */
  2771.  
  2772.                 }
  2773.  
  2774.  
  2775.  
  2776.  
  2777.  
  2778.  
  2779.  
  2780.  
  2781.  
  2782.  
  2783.  
  2784.  
  2785.  
  2786.  
  2787.  
  2788.  
  2789.  
  2790.  
  2791.  
  2792.  
  2793.  
  2794.  
  2795.  
  2796.  
  2797.  
  2798.  
  2799.  
  2800.  
  2801.  
  2802.  
  2803.  
  2804.                                           - 42 -
  2805.  
  2806.  
  2807.  
  2808.  
  2809.                                  Copyright Ron Albury 1988
  2810.  
  2811.           FUNCTION Htest
  2812.                    Htest
  2813.  
  2814.              PURPOSE
  2815.  
  2816.                 Tests a  hash node  to detect memory corruption or to verify
  2817.              that the element is from the indicated table.
  2818.  
  2819.              PARAMETERS
  2820.  
  2821.                 Root: (Input)
  2822.                    The root of the table being accessed.
  2823.  
  2824.                 Node: (Input)
  2825.                    The node of the table to be tested.
  2826.  
  2827.              RETURNS
  2828.  
  2829.                 Integer indicating status of test.
  2830.                    0 = Success.
  2831.                    1 = Corrupted memory, or indicated element is not part
  2832.                        of this table.
  2833.  
  2834.              PROTOTYPE
  2835.  
  2836.                 int Htest (Hroot root, Hnode node);
  2837.  
  2838.              DEBUG
  2839.  
  2840.                 The debug library (only) will report:
  2841.                    1) Null root.
  2842.                    2) Null node.
  2843.  
  2844.  
  2845.  
  2846.  
  2847.  
  2848.  
  2849.  
  2850.  
  2851.  
  2852.  
  2853.  
  2854.  
  2855.  
  2856.  
  2857.  
  2858.  
  2859.  
  2860.  
  2861.  
  2862.  
  2863.  
  2864.  
  2865.  
  2866.  
  2867.  
  2868.  
  2869.  
  2870.  
  2871.                                           - 43 -
  2872.  
  2873.  
  2874.  
  2875.  
  2876.                                  Copyright Ron Albury 1988
  2877.  
  2878.              EXAMPLE
  2879.  
  2880.                 #include "salve.h"
  2881.  
  2882.                 main()
  2883.                 {
  2884.                    int    status;
  2885.                    struct UserRec *u;
  2886.                    Hnode  node;
  2887.                    Hroot  root;
  2888.  
  2889.                    /* open the hash table */
  2890.                       :   :   :
  2891.                    /* add records to the table */
  2892.                       :   :   :
  2893.  
  2894.                    /* find the first node with a given key *
  2895.                    node = Hfind (root, "Key Field", &u);
  2896.  
  2897.                    /* test that node for corruption */
  2898.                    status = Htest (root, node);
  2899.  
  2900.                       :   :   :
  2901.                 }
  2902.  
  2903.  
  2904.  
  2905.  
  2906.  
  2907.  
  2908.  
  2909.  
  2910.  
  2911.  
  2912.  
  2913.  
  2914.  
  2915.  
  2916.  
  2917.  
  2918.  
  2919.  
  2920.  
  2921.  
  2922.  
  2923.  
  2924.  
  2925.  
  2926.  
  2927.  
  2928.  
  2929.  
  2930.  
  2931.  
  2932.  
  2933.  
  2934.  
  2935.  
  2936.  
  2937.                                           - 44 -
  2938.  
  2939.  
  2940.  
  2941.  
  2942.                                  Copyright Ron Albury 1988
  2943.  
  2944.           LINKED LIST CLASS
  2945.           LINKED LIST CLASS
  2946.  
  2947.                 A linked  list is probably the most fundamental dynamic data
  2948.              structure.   It allows  you to  string together  multiple items
  2949.              into a list.  Unlike a set, you can store non-ordinal values in
  2950.              the list  (such as a record), can store duplicates in the list,
  2951.              and can arrange the list in different orders.
  2952.  
  2953.                 The ordering  of a list can be based on time (First In First
  2954.                                                               F     I  F    
  2955.              Out: Queue; Last In First Out: Stack), on a key value (sorted),
  2956.              O           L    I  F     O                                    
  2957.              or on  any other  basis you  can think  of (e.g.  Most Recently
  2958.                                                          e.g.  M    R       
  2959.              Used).
  2960.              U     
  2961.  
  2962.                 I generally  use lists as my primary method of storing data,
  2963.              and then  use  the  hash  table,  tree,  and/or  sparse  matrix
  2964.              routines to  provide indices  into the  list.  You can use them
  2965.              for what ever you want.
  2966.  
  2967.                 One way to code '1 to many' relationships (e.g. one club has
  2968.              many members)  is with  multiple lists.   The first list is the
  2969.              '1' list (such as clubs).  Each record of the '1' list contains
  2970.              in it  the root  for the 'many' list (members).  To find all of
  2971.              the members  of a  specific club you could scan (or index into)
  2972.              the club list, and then scan the sub-list containing all of the
  2973.              members.
  2974.  
  2975.                 You can  even support  'm to n' relationships (e.g. one club
  2976.              has many  members, and  one member belongs to many clubs).  You
  2977.              have one  list of  clubs, one list of members, and then a third
  2978.              list of  'belongs to'  which is  a sub-list  to the  other two.
  2979.              Although you  would (probably) rarely want to scan the 'belongs
  2980.              to' list,  it is best to keep the records in a list so that you
  2981.              don't loose them and end up with un-free'd memory lying around.
  2982.              Some people  will go  so far  as to  have a  master list of all
  2983.              allocated records, no matter what set they belong to.
  2984.  
  2985.  
  2986.  
  2987.  
  2988.  
  2989.  
  2990.  
  2991.  
  2992.  
  2993.  
  2994.  
  2995.  
  2996.  
  2997.  
  2998.  
  2999.  
  3000.  
  3001.  
  3002.  
  3003.  
  3004.  
  3005.  
  3006.  
  3007.  
  3008.                                           - 45 -
  3009.  
  3010.  
  3011.  
  3012.  
  3013.                                  Copyright Ron Albury 1988
  3014.  
  3015.           FUNCTION Ladd_after
  3016.                    Ladd_after
  3017.  
  3018.              PURPOSE
  3019.  
  3020.                 Adds a new data element to the list after the indicated list
  3021.              node.
  3022.  
  3023.              PARAMETERS
  3024.  
  3025.                 Root: (Input)
  3026.                    The root of the list being accessed.
  3027.  
  3028.                 Data: (Input)
  3029.                    The data element to be placed into the list.
  3030.  
  3031.                 Node:  (Input)
  3032.                    The list  node of  a data element already in the list.
  3033.                    This existing  node will  be used  to position the new
  3034.                    data element.
  3035.  
  3036.              RETURNS
  3037.  
  3038.                 List node of the added element.
  3039.  
  3040.              PROTOTYPE
  3041.  
  3042.                 Lnode Ladd_after
  3043.                    (Lroot root, void *data, Lnode node);
  3044.  
  3045.              DEBUG
  3046.  
  3047.                 The debug library (only) will report:
  3048.                    1) Null root.
  3049.                    2) Null data.
  3050.                    3) Null node.
  3051.                    4) Malloc failure.
  3052.                    5) Internal consistency test.
  3053.  
  3054.  
  3055.  
  3056.  
  3057.  
  3058.  
  3059.  
  3060.  
  3061.  
  3062.  
  3063.  
  3064.  
  3065.  
  3066.  
  3067.  
  3068.  
  3069.  
  3070.  
  3071.  
  3072.  
  3073.  
  3074.  
  3075.                                           - 46 -
  3076.  
  3077.  
  3078.  
  3079.  
  3080.                                  Copyright Ron Albury 1988
  3081.  
  3082.              EXAMPLE
  3083.  
  3084.                 #include "salve.h"
  3085.  
  3086.                 main()
  3087.                 {
  3088.                    struct UserRec *u;
  3089.                    Lnode  node1, node2;
  3090.                    Lroot  root;
  3091.  
  3092.                    /* open the list */
  3093.                       :   :   :
  3094.  
  3095.                    /* create a new element for the list */
  3096.                    u = malloc(sizeof(struct UserRec));
  3097.                    assign_values(u);
  3098.  
  3099.                    /* add the new record to the head of the list */
  3100.                    node1 = Ladd_first (root, u);
  3101.  
  3102.                    /* create another new element for the list */
  3103.                    u = malloc(sizeof(struct UserRec));
  3104.                    assign_values(u);
  3105.  
  3106.                    /* add the record second in the list */
  3107.                    node2 = Ladd_after (root, u, node1);
  3108.  
  3109.                    /* use the list */
  3110.                       :   :   :
  3111.                    /* close the list */
  3112.                 }
  3113.  
  3114.  
  3115.  
  3116.  
  3117.  
  3118.  
  3119.  
  3120.  
  3121.  
  3122.  
  3123.  
  3124.  
  3125.  
  3126.  
  3127.  
  3128.  
  3129.  
  3130.  
  3131.  
  3132.  
  3133.  
  3134.  
  3135.  
  3136.  
  3137.  
  3138.  
  3139.  
  3140.  
  3141.                                           - 47 -
  3142.  
  3143.  
  3144.  
  3145.  
  3146.                                  Copyright Ron Albury 1988
  3147.  
  3148.           FUNCTION Ladd_before
  3149.                    Ladd_before
  3150.  
  3151.              PURPOSE
  3152.  
  3153.                 Adds a  new data  element to  the list  before the indicated
  3154.              list node.
  3155.  
  3156.              PARAMETERS
  3157.  
  3158.                 Root: (Input)
  3159.                    The root of the list being accessed.
  3160.  
  3161.                 Data: (Input)
  3162.                    The data element to be placed into the list.
  3163.  
  3164.                 Node:  (Input)
  3165.                    The list  node of  a data element already in the list.
  3166.                    This existing  node will  be used  to position the new
  3167.                    data element.
  3168.  
  3169.              RETURNS
  3170.  
  3171.                 List node of the added data element.
  3172.  
  3173.              PROTOTYPE
  3174.  
  3175.                 Lnode Ladd_before
  3176.                    (Lroot root, void *data, Lnode node);
  3177.  
  3178.              DEBUG
  3179.  
  3180.                 The debug library (only) will report:
  3181.                    1) Null root.
  3182.                    2) Null data.
  3183.                    3) Null node.
  3184.                    4) Malloc failure.
  3185.                    5) Internal consistency test.
  3186.  
  3187.  
  3188.  
  3189.  
  3190.  
  3191.  
  3192.  
  3193.  
  3194.  
  3195.  
  3196.  
  3197.  
  3198.  
  3199.  
  3200.  
  3201.  
  3202.  
  3203.  
  3204.  
  3205.  
  3206.  
  3207.  
  3208.                                           - 48 -
  3209.  
  3210.  
  3211.  
  3212.  
  3213.                                  Copyright Ron Albury 1988
  3214.  
  3215.              EXAMPLE
  3216.  
  3217.                 #include "salve.h"
  3218.  
  3219.                 main()
  3220.                 {
  3221.                    struct UserRec *u;
  3222.                    Lnode  node1, node2;
  3223.                    Lroot  root;
  3224.  
  3225.                    /* open the list */
  3226.                       :   :   :
  3227.  
  3228.                    /* create a new element for the list */
  3229.                    u = malloc(sizeof(struct UserRec));
  3230.                    assign_values(u);
  3231.  
  3232.                    /* add the new record to the end of the list */
  3233.                    node1 = Ladd_last (root, u);
  3234.  
  3235.                    /* create another new element for the list */
  3236.                    u = malloc(sizeof(struct UserRec));
  3237.                    assign_values(u);
  3238.  
  3239.                    /* add the record next to the end of the list */
  3240.                    node2 = Ladd_before (root, u, node1);
  3241.  
  3242.                    /* use the list */
  3243.                       :   :   :
  3244.                    /* close the list */
  3245.                 }
  3246.  
  3247.  
  3248.  
  3249.  
  3250.  
  3251.  
  3252.  
  3253.  
  3254.  
  3255.  
  3256.  
  3257.  
  3258.  
  3259.  
  3260.  
  3261.  
  3262.  
  3263.  
  3264.  
  3265.  
  3266.  
  3267.  
  3268.  
  3269.  
  3270.  
  3271.  
  3272.  
  3273.  
  3274.                                           - 49 -
  3275.  
  3276.  
  3277.  
  3278.  
  3279.                                  Copyright Ron Albury 1988
  3280.  
  3281.           FUNCTION Ladd_first
  3282.                    Ladd_first
  3283.  
  3284.              PURPOSE
  3285.  
  3286.                 Adds a  data element  to the  head (first  position) of  the
  3287.              indicated list.
  3288.  
  3289.              PARAMETERS
  3290.  
  3291.                 Root: (Input)
  3292.                    The root of the list being accessed.
  3293.  
  3294.                 Data: (Input)
  3295.                    The data   element  to be  placed into the list at the
  3296.                    first position.
  3297.  
  3298.              RETURNS
  3299.  
  3300.                 List node of the added element.
  3301.  
  3302.              PROTOTYPE
  3303.  
  3304.                 Lnode Ladd_first
  3305.                    (Lroot root, void *data);
  3306.  
  3307.              DEBUG
  3308.  
  3309.                 The debug library (only) will report:
  3310.                    1) Null root.
  3311.                    2) Null data.
  3312.                    3) Malloc failure.
  3313.  
  3314.  
  3315.  
  3316.  
  3317.  
  3318.  
  3319.  
  3320.  
  3321.  
  3322.  
  3323.  
  3324.  
  3325.  
  3326.  
  3327.  
  3328.  
  3329.  
  3330.  
  3331.  
  3332.  
  3333.  
  3334.  
  3335.  
  3336.  
  3337.  
  3338.  
  3339.  
  3340.  
  3341.                                           - 50 -
  3342.  
  3343.  
  3344.  
  3345.  
  3346.                                  Copyright Ron Albury 1988
  3347.  
  3348.              EXAMPLE
  3349.  
  3350.                 #include "salve.h"
  3351.  
  3352.                 main()
  3353.                 {
  3354.                    struct UserRec *u;
  3355.                    Lnode  node;
  3356.                    Lroot  root;
  3357.  
  3358.                    /* open the list */
  3359.                       :   :   :
  3360.  
  3361.                    /* create a new element for the list */
  3362.                    u = malloc(sizeof(struct UserRec));
  3363.                    assign_values(u);
  3364.  
  3365.                    /* add the new record to the head of the list */
  3366.                    node = Ladd_first (root, u);
  3367.  
  3368.                    /* use the list */
  3369.                       :   :   :
  3370.                    /* close the list */
  3371.                 }
  3372.  
  3373.  
  3374.  
  3375.  
  3376.  
  3377.  
  3378.  
  3379.  
  3380.  
  3381.  
  3382.  
  3383.  
  3384.  
  3385.  
  3386.  
  3387.  
  3388.  
  3389.  
  3390.  
  3391.  
  3392.  
  3393.  
  3394.  
  3395.  
  3396.  
  3397.  
  3398.  
  3399.  
  3400.  
  3401.  
  3402.  
  3403.  
  3404.  
  3405.  
  3406.  
  3407.                                           - 51 -
  3408.  
  3409.  
  3410.  
  3411.  
  3412.                                  Copyright Ron Albury 1988
  3413.  
  3414.           FUNCTION Ladd_last
  3415.                    Ladd_last
  3416.  
  3417.              PURPOSE
  3418.  
  3419.                 Adds a  data   element to  the tail  (last position)  of the
  3420.              indicated list.
  3421.  
  3422.              PARAMETERS
  3423.  
  3424.                 Root: (Input)
  3425.                    The root of the list being accessed.
  3426.  
  3427.                 Data: (Input)
  3428.                    The data element to be placed at the end of the list.
  3429.  
  3430.              RETURNS
  3431.  
  3432.                 List node of the added element.
  3433.  
  3434.              PROTOTYPE
  3435.  
  3436.                 Lnode Ladd_last
  3437.                    (Lroot root, void *data);
  3438.  
  3439.              DEBUG
  3440.  
  3441.                 The debug library (only) will report:
  3442.                    1) Null root.
  3443.                    2) Null data.
  3444.                    3) Malloc failure.
  3445.  
  3446.  
  3447.  
  3448.  
  3449.  
  3450.  
  3451.  
  3452.  
  3453.  
  3454.  
  3455.  
  3456.  
  3457.  
  3458.  
  3459.  
  3460.  
  3461.  
  3462.  
  3463.  
  3464.  
  3465.  
  3466.  
  3467.  
  3468.  
  3469.  
  3470.  
  3471.  
  3472.  
  3473.  
  3474.                                           - 52 -
  3475.  
  3476.  
  3477.  
  3478.  
  3479.                                  Copyright Ron Albury 1988
  3480.  
  3481.              EXAMPLE
  3482.  
  3483.                 #include "salve.h"
  3484.  
  3485.                 main()
  3486.                 {
  3487.                    struct UserRec *u;
  3488.                    Lnode  node;
  3489.                    Lroot  root;
  3490.  
  3491.                    /* open the list */
  3492.                       :   :   :
  3493.  
  3494.                    /* create a new data element for the list */
  3495.                    u = malloc(sizeof(struct UserRec));
  3496.  
  3497.                    /* assign values to the new data element */
  3498.                    assign_values(u);
  3499.  
  3500.                    /* add the new data to the tail of the list */
  3501.                    node = Ladd_last (root, u);
  3502.  
  3503.                    /* use the list */
  3504.                       :   :   :
  3505.  
  3506.                    /* close the list */
  3507.  
  3508.                 }
  3509.  
  3510.  
  3511.  
  3512.  
  3513.  
  3514.  
  3515.  
  3516.  
  3517.  
  3518.  
  3519.  
  3520.  
  3521.  
  3522.  
  3523.  
  3524.  
  3525.  
  3526.  
  3527.  
  3528.  
  3529.  
  3530.  
  3531.  
  3532.  
  3533.  
  3534.  
  3535.  
  3536.  
  3537.  
  3538.  
  3539.  
  3540.                                           - 53 -
  3541.  
  3542.  
  3543.  
  3544.  
  3545.                                  Copyright Ron Albury 1988
  3546.  
  3547.           FUNCTION Ladd_order
  3548.                    Ladd_order
  3549.  
  3550.              PURPOSE
  3551.  
  3552.                 Adds a  data element  to the indicated list in sorted order.
  3553.              This function  ASSUMES that  ALL elements in the list have been
  3554.                                           ALL                               
  3555.              added IN  ORDER, and  that the  order has not been corrupted by
  3556.              other calls  (e.g. you  may  NOT  use  Lmake_first,  Ladd_last,
  3557.                                           NOT                               
  3558.              etc.).  Violate this assumption at your own risk.
  3559.  
  3560.              PARAMETERS
  3561.  
  3562.                 Root: (Input)
  3563.                    The root of the list being accessed.
  3564.  
  3565.                 Data: (Input)
  3566.                    The data element to be placed into the list.
  3567.  
  3568.                 Key:  (Input)
  3569.                    The key  field to  pass to  the compare  function  for
  3570.                    determining order.   This  field may be a pointer to a
  3571.                    record of the same type as the data element, or it may
  3572.                    be a pointer to some other structure (e.g just a field
  3573.                    of the data element record structure).
  3574.  
  3575.                 Dupe: (Input)
  3576.                    OK_DUPE means  duplicates are permitted, NO_DUPE means
  3577.                    duplicates indicate an error condition.
  3578.  
  3579.              RETURNS
  3580.  
  3581.                 An Lnode pointer
  3582.                    Success: List node of the added element.
  3583.                    Failure: NULL (duplicate entry found).
  3584.  
  3585.              PROTOTYPE
  3586.  
  3587.                 Lnode Ladd_order
  3588.                    (Lroot root, void *data, void *key, int dupe);
  3589.  
  3590.              DEBUG
  3591.  
  3592.                 The debug library (only) will report:
  3593.                    1) Null root.
  3594.                    2) Null data.
  3595.                    3) Null key.
  3596.                    4) Internal consistency test.
  3597.  
  3598.  
  3599.  
  3600.  
  3601.  
  3602.  
  3603.  
  3604.  
  3605.  
  3606.  
  3607.  
  3608.  
  3609.                                           - 54 -
  3610.  
  3611.  
  3612.  
  3613.  
  3614.                                  Copyright Ron Albury 1988
  3615.  
  3616.              EXAMPLE
  3617.  
  3618.                 #include "salve.h"
  3619.  
  3620.                 main()
  3621.                 {
  3622.                    struct UserRec *u;
  3623.                    char   key[20];
  3624.                    Lnode  node;
  3625.                    Lroot  root;
  3626.  
  3627.                    /* open the list */
  3628.                       :   :   :
  3629.  
  3630.                    /* create a new data element for the list */
  3631.                    u = malloc(sizeof(struct UserRec));
  3632.  
  3633.                    /* assign values to the data element */
  3634.                    gets (key);
  3635.                    assign_values(u, key);
  3636.  
  3637.                    /* add the new record to the list */
  3638.                    node = Ladd_order (root, u, key, NO_DUPE);
  3639.  
  3640.                    /* use the list */
  3641.                       :   :   :
  3642.                    /* close the list */
  3643.                 }
  3644.  
  3645.  
  3646.  
  3647.  
  3648.  
  3649.  
  3650.  
  3651.  
  3652.  
  3653.  
  3654.  
  3655.  
  3656.  
  3657.  
  3658.  
  3659.  
  3660.  
  3661.  
  3662.  
  3663.  
  3664.  
  3665.  
  3666.  
  3667.  
  3668.  
  3669.  
  3670.  
  3671.  
  3672.  
  3673.  
  3674.  
  3675.                                           - 55 -
  3676.  
  3677.  
  3678.  
  3679.  
  3680.                                  Copyright Ron Albury 1988
  3681.  
  3682.           FUNCTION Lcard
  3683.                    Lcard
  3684.  
  3685.              PURPOSE
  3686.  
  3687.                 Returns the cardinality (number of elements) of the list.
  3688.  
  3689.              PARAMETERS
  3690.  
  3691.                 Root: (Input)
  3692.                    The root of the list being accessed.
  3693.  
  3694.              RETURNS
  3695.  
  3696.                 Long integer  indicating number of elements currently in the
  3697.              list.
  3698.  
  3699.              PROTOTYPE
  3700.  
  3701.                 long Lcard
  3702.                    (Lroot root);
  3703.  
  3704.              DEBUG
  3705.  
  3706.                 The debug library (only) will report:
  3707.                    1) Null root.
  3708.  
  3709.              EXAMPLE
  3710.  
  3711.                 #include "salve.h"
  3712.  
  3713.                 main()
  3714.                 {
  3715.                    Lroot  root;
  3716.                    long    quan;
  3717.  
  3718.                    /* open the list */
  3719.                       :   :   :
  3720.  
  3721.                    /* use the list */
  3722.                       :   :   :
  3723.  
  3724.                    /* find out how elements are in the list */
  3725.                    quan = Lcard (root);
  3726.  
  3727.                    /* close the list */
  3728.                 }
  3729.  
  3730.  
  3731.  
  3732.  
  3733.  
  3734.  
  3735.  
  3736.  
  3737.  
  3738.  
  3739.  
  3740.  
  3741.  
  3742.                                           - 56 -
  3743.  
  3744.  
  3745.  
  3746.  
  3747.                                  Copyright Ron Albury 1988
  3748.  
  3749.           FUNCTION Lclose
  3750.                    Lclose
  3751.  
  3752.              PURPOSE
  3753.  
  3754.                 Closes a  previously opened linked list.  All nodes and data
  3755.              elements must  have been  removed from the list before the list
  3756.              is closed.
  3757.  
  3758.              PARAMETERS
  3759.  
  3760.                 Root: (Input/Output)
  3761.                    The root  of the  list being closed.  This must be the
  3762.                    root parameter  which  was  returned  from  the  Lopen
  3763.                    function when the list was opened.
  3764.  
  3765.              RETURNS
  3766.  
  3767.                 An integer indicating the status of the call.
  3768.                    0 = Success.
  3769.                    1 =  Elements were  left in the list.  Remove them and
  3770.                        try again.
  3771.  
  3772.              PROTOTYPE
  3773.  
  3774.                 int Lclose
  3775.                    (Lroot *root);
  3776.  
  3777.              DEBUG
  3778.  
  3779.                 Both libraries will report:
  3780.                    1) Null root.
  3781.                    2) Internal consistency test.
  3782.  
  3783.              EXAMPLE
  3784.  
  3785.                 #include "salve.h"
  3786.  
  3787.                 main()
  3788.                 {
  3789.                    int   status;
  3790.                    Lroot root;
  3791.  
  3792.                    /* open the list */
  3793.                       :   :   :
  3794.                    /* use the list */
  3795.                       :   :   :
  3796.                    status = Lclose (&root);
  3797.                 }
  3798.  
  3799.  
  3800.  
  3801.  
  3802.  
  3803.  
  3804.  
  3805.  
  3806.  
  3807.  
  3808.  
  3809.                                           - 57 -
  3810.  
  3811.  
  3812.  
  3813.  
  3814.                                  Copyright Ron Albury 1988
  3815.  
  3816.           FUNCTION Lfind
  3817.                    Lfind
  3818.  
  3819.              PURPOSE
  3820.  
  3821.                 Does a  sequential search  of a  list to find a data element
  3822.              with a  specified key  field.   The list  does not  need to  be
  3823.              inorder for this function to work.
  3824.  
  3825.              PARAMETERS
  3826.  
  3827.                 Root:  (Input)
  3828.                    The root of the list being accessed.
  3829.  
  3830.                 Key:   (Input)
  3831.                    The key  field to  be used  in finding  the  requested
  3832.                    element.
  3833.  
  3834.                 Found: (Output)
  3835.                    The first element in the list with a matching key.
  3836.  
  3837.                 Flag:  (Input)
  3838.                    Either FIND_EQ  (if there  must be  an exact match) or
  3839.                    FIND_GE (if  you are  willing to stop searching at the
  3840.                    first element  with a  key greater  or  equal  to  the
  3841.                    search key).   For performance reasons it is suggested
  3842.                    that you  always use FIND_GE when searching an ordered
  3843.                              always                                      
  3844.                    list.
  3845.  
  3846.              RETURNS
  3847.  
  3848.                 An Lnode pointer
  3849.                    Success: List node of the found element.
  3850.                    Failure: NULL (node not found).
  3851.  
  3852.              PROTOTYPE
  3853.  
  3854.                 Lnode Lfind
  3855.                    (Lroot root, void *key, void **found, int flag);
  3856.  
  3857.              DEBUG
  3858.  
  3859.                 The debug library (only) will report:
  3860.                    1) Null root.
  3861.                    2) Null key.
  3862.                    3) Null found.
  3863.                    4) Internal consistency test.
  3864.  
  3865.  
  3866.  
  3867.  
  3868.  
  3869.  
  3870.  
  3871.  
  3872.  
  3873.  
  3874.  
  3875.  
  3876.  
  3877.                                           - 58 -
  3878.  
  3879.  
  3880.  
  3881.  
  3882.                                  Copyright Ron Albury 1988
  3883.  
  3884.              EXAMPLE
  3885.  
  3886.                 #include "salve.h"
  3887.  
  3888.                 main()
  3889.                 {
  3890.                    struct UserRec *u;
  3891.                    Lnode  node;
  3892.                    Lroot  root;
  3893.  
  3894.                    /* open the list */
  3895.                    /* add records to the list - NOT in order */
  3896.                       :   :   :
  3897.  
  3898.                    /* find the first node with a given key *
  3899.                    node = Lfind (root, "Key Field", &u, FIND_EQ);
  3900.  
  3901.                    /* close the list */
  3902.                 }
  3903.  
  3904.  
  3905.  
  3906.  
  3907.  
  3908.  
  3909.  
  3910.  
  3911.  
  3912.  
  3913.  
  3914.  
  3915.  
  3916.  
  3917.  
  3918.  
  3919.  
  3920.  
  3921.  
  3922.  
  3923.  
  3924.  
  3925.  
  3926.  
  3927.  
  3928.  
  3929.  
  3930.  
  3931.  
  3932.  
  3933.  
  3934.  
  3935.  
  3936.  
  3937.  
  3938.  
  3939.  
  3940.  
  3941.  
  3942.  
  3943.                                           - 59 -
  3944.  
  3945.  
  3946.  
  3947.  
  3948.                                  Copyright Ron Albury 1988
  3949.  
  3950.           FUNCTION Lfind_after
  3951.                    Lfind_after
  3952.  
  3953.              PURPOSE
  3954.  
  3955.                 Finds the  data element in the list after the indicated list
  3956.              node.
  3957.  
  3958.              PARAMETERS
  3959.  
  3960.                 Root:  (Input)
  3961.                    The root of the list being accessed.
  3962.  
  3963.                 Node:  (Input)
  3964.                    The list  node to  be used  in finding  the  requested
  3965.                    element.
  3966.  
  3967.                 Found: (Output)
  3968.                    The next element in the list.
  3969.  
  3970.              RETURNS
  3971.  
  3972.                 An Lnode pointer
  3973.                    Success: List node of the found element.
  3974.                    Failure: NULL (node not found).
  3975.  
  3976.              PROTOTYPE
  3977.  
  3978.                 Lnode Lfind_after
  3979.                    (Lroot root, Lnode node, void **found);
  3980.  
  3981.              DEBUG
  3982.  
  3983.                 The debug library (only) will report:
  3984.                    1) Null root.
  3985.                    2) Null node.
  3986.                    3) Null found.
  3987.  
  3988.  
  3989.  
  3990.  
  3991.  
  3992.  
  3993.  
  3994.  
  3995.  
  3996.  
  3997.  
  3998.  
  3999.  
  4000.  
  4001.  
  4002.  
  4003.  
  4004.  
  4005.  
  4006.  
  4007.  
  4008.  
  4009.  
  4010.                                           - 60 -
  4011.  
  4012.  
  4013.  
  4014.  
  4015.                                  Copyright Ron Albury 1988
  4016.  
  4017.              EXAMPLE
  4018.  
  4019.                 #include "salve.h"
  4020.  
  4021.                 main()
  4022.                 {
  4023.                    struct UserRec *u;
  4024.                    Lnode  node1, node2;
  4025.                    Lroot  root;
  4026.  
  4027.                    /* open the list */
  4028.                       :   :   :
  4029.                    /* add records to the list */
  4030.                       :   :   :
  4031.  
  4032.                    /* find the first element in the list *
  4033.                    node1 = Lfind_first (root, &u);
  4034.  
  4035.                    /* find the second element in the list *
  4036.                    node2 = Lfind_after (root, node1, &u);
  4037.  
  4038.                    /* close the list */
  4039.                 }
  4040.  
  4041.  
  4042.  
  4043.  
  4044.  
  4045.  
  4046.  
  4047.  
  4048.  
  4049.  
  4050.  
  4051.  
  4052.  
  4053.  
  4054.  
  4055.  
  4056.  
  4057.  
  4058.  
  4059.  
  4060.  
  4061.  
  4062.  
  4063.  
  4064.  
  4065.  
  4066.  
  4067.  
  4068.  
  4069.  
  4070.  
  4071.  
  4072.  
  4073.  
  4074.  
  4075.  
  4076.                                           - 61 -
  4077.  
  4078.  
  4079.  
  4080.  
  4081.                                  Copyright Ron Albury 1988
  4082.  
  4083.           FUNCTION Lfind_before
  4084.                    Lfind_before
  4085.  
  4086.              PURPOSE
  4087.  
  4088.                 Finds the data element in the list before the indicated list
  4089.              node.
  4090.  
  4091.              PARAMETERS
  4092.  
  4093.                 Root:  (Input)
  4094.                    The root of the list being accessed.
  4095.  
  4096.                 Node:  (Input)
  4097.                    The list node to be used in finding the requested data
  4098.                    element.
  4099.  
  4100.                 Found: (Output)
  4101.                    The prior element in the list.
  4102.  
  4103.              RETURNS
  4104.  
  4105.                 An Lnode pointer
  4106.                    Success: List node of the found element.
  4107.                    Failure: NULL (node not found).
  4108.  
  4109.              PROTOTYPE
  4110.  
  4111.                 Lnode Lfind_before
  4112.                    (Lroot root, Lnode node, void **found);
  4113.  
  4114.              DEBUG
  4115.  
  4116.                 The debug library (only) will report:
  4117.                    1) Null root.
  4118.                    2) Null node.
  4119.                    3) Null found.
  4120.  
  4121.  
  4122.  
  4123.  
  4124.  
  4125.  
  4126.  
  4127.  
  4128.  
  4129.  
  4130.  
  4131.  
  4132.  
  4133.  
  4134.  
  4135.  
  4136.  
  4137.  
  4138.  
  4139.  
  4140.  
  4141.  
  4142.  
  4143.                                           - 62 -
  4144.  
  4145.  
  4146.  
  4147.  
  4148.                                  Copyright Ron Albury 1988
  4149.  
  4150.              EXAMPLE
  4151.  
  4152.                 #include "salve.h"
  4153.  
  4154.                 main()
  4155.                 {
  4156.                    struct UserRec *u;
  4157.                    Lnode  node1, node2;
  4158.                    Lroot  root;
  4159.  
  4160.                    /* open the list */
  4161.                       :   :   :
  4162.                    /* add records to the list */
  4163.                       :   :   :
  4164.  
  4165.                    /* find the last element in the list *
  4166.                    node1 = Lfind_last (root, &u);
  4167.  
  4168.                    /* find the next to the last element in the list *
  4169.                    node2 = Lfind_before (root, node1, &u);
  4170.  
  4171.                    /* close the list */
  4172.                 }
  4173.  
  4174.  
  4175.  
  4176.  
  4177.  
  4178.  
  4179.  
  4180.  
  4181.  
  4182.  
  4183.  
  4184.  
  4185.  
  4186.  
  4187.  
  4188.  
  4189.  
  4190.  
  4191.  
  4192.  
  4193.  
  4194.  
  4195.  
  4196.  
  4197.  
  4198.  
  4199.  
  4200.  
  4201.  
  4202.  
  4203.  
  4204.  
  4205.  
  4206.  
  4207.  
  4208.  
  4209.                                           - 63 -
  4210.  
  4211.  
  4212.  
  4213.  
  4214.                                  Copyright Ron Albury 1988
  4215.  
  4216.           FUNCTION Lfind_first
  4217.                    Lfind_first
  4218.  
  4219.              PURPOSE
  4220.  
  4221.                 Finds the first data element stored in the indicated list.
  4222.  
  4223.              PARAMETERS
  4224.  
  4225.                 Root:  (Input)
  4226.                    The root of the list being accessed.
  4227.  
  4228.                 Found: (Output)
  4229.                    The first data element in the list.
  4230.  
  4231.              RETURNS
  4232.  
  4233.                 An Lnode pointer
  4234.                    Success: List node of the found element.
  4235.                    Failure: NULL (node not found).
  4236.  
  4237.              PROTOTYPE
  4238.  
  4239.                 Lnode Lfind_first
  4240.                    (Lroot root, void **found);
  4241.  
  4242.              DEBUG
  4243.  
  4244.                 The debug library (only) will report:
  4245.                    1) Null root.
  4246.                    2) Null found.
  4247.  
  4248.              EXAMPLE
  4249.  
  4250.                 #include "salve.h"
  4251.  
  4252.                 main()
  4253.                 {
  4254.                    struct UserRec *u;
  4255.                    Lnode  node;
  4256.                    Lroot  root;
  4257.  
  4258.                    /* open the list */
  4259.                       :   :   :
  4260.                    /* add records to the list */
  4261.                       :   :   :
  4262.  
  4263.                    /* find the first element in the list */
  4264.                    node = Lfind_first (root, &u);
  4265.  
  4266.                    /* use the list */
  4267.                       :   :   :
  4268.                    /* close the list */
  4269.                 }
  4270.  
  4271.  
  4272.  
  4273.  
  4274.  
  4275.  
  4276.                                           - 64 -
  4277.  
  4278.  
  4279.  
  4280.  
  4281.                                  Copyright Ron Albury 1988
  4282.  
  4283.           FUNCTION Lfind_last
  4284.                    Lfind_last
  4285.  
  4286.              PURPOSE
  4287.  
  4288.                 Finds the last data element of the indicated list.
  4289.  
  4290.              PARAMETERS
  4291.  
  4292.                 Root:  (Input)
  4293.                    The root of the list being accessed.
  4294.  
  4295.                 Found: (Output)
  4296.                    The last data element in the list.
  4297.  
  4298.              RETURNS
  4299.  
  4300.                 An Lnode pointer
  4301.                    Success: List node of the found element.
  4302.                    Failure: NULL (node not found).
  4303.  
  4304.              PROTOTYPE
  4305.  
  4306.                 Lnode Lfind_last
  4307.                    (Lroot root, void **found_data);
  4308.  
  4309.              DEBUG
  4310.  
  4311.                 The debug library (only) will report:
  4312.                    1) Null root.
  4313.                    2) Null found.
  4314.  
  4315.              EXAMPLE
  4316.  
  4317.                 #include "salve.h"
  4318.  
  4319.                 main()
  4320.                 {
  4321.                    struct UserRec *u;
  4322.                    Lnode  node;
  4323.                    Lroot  root;
  4324.  
  4325.                    /* open the list */
  4326.                       :   :   :
  4327.                    /* add records to the list */
  4328.                       :   :   :
  4329.  
  4330.                    /* find the last element in the list */
  4331.                    node = Lfind_last (root, &u);
  4332.  
  4333.                    /* use the list */
  4334.                       :   :   :
  4335.                    /* close the list */
  4336.                 }
  4337.  
  4338.  
  4339.  
  4340.  
  4341.  
  4342.  
  4343.                                           - 65 -
  4344.  
  4345.  
  4346.  
  4347.  
  4348.                                  Copyright Ron Albury 1988
  4349.  
  4350.           FUNCTION Lfind_next
  4351.                    Lfind_next
  4352.  
  4353.              PURPOSE
  4354.  
  4355.                 Finds next  data element  in the list with the indicated key
  4356.              field.   This function  is primarily  used with  unsorted lists
  4357.              with non-unique entries.
  4358.  
  4359.              PARAMETERS
  4360.  
  4361.                 Root:  (Input)
  4362.                    The root of the list being accessed.
  4363.  
  4364.                 Node:  (Input)
  4365.                    The list  node to be used as the starting point in the
  4366.                    search for the requested element.
  4367.  
  4368.                 Key:   (Input)
  4369.                    The key field to be used in finding the requested data
  4370.                    element.
  4371.  
  4372.                 Found: (Output)
  4373.                    The next element in the list with a matching key.
  4374.  
  4375.              RETURNS
  4376.  
  4377.                 An Lnode pointer
  4378.                    Success: List node of the found element.
  4379.                    Failure: NULL (node not found).
  4380.  
  4381.              PROTOTYPE
  4382.  
  4383.                 Lnode Lfind_next
  4384.                    (Lroot root, Lnode node, void *key, void **found);
  4385.  
  4386.              DEBUG
  4387.  
  4388.                 The debug library (only) will report:
  4389.                    1) Null root.
  4390.                    2) Null node.
  4391.                    3) Null key.
  4392.                    4) Null found.
  4393.                    5) Internal consistency test.
  4394.  
  4395.  
  4396.  
  4397.  
  4398.  
  4399.  
  4400.  
  4401.  
  4402.  
  4403.  
  4404.  
  4405.  
  4406.  
  4407.  
  4408.  
  4409.  
  4410.                                           - 66 -
  4411.  
  4412.  
  4413.  
  4414.  
  4415.                                  Copyright Ron Albury 1988
  4416.  
  4417.              EXAMPLE
  4418.  
  4419.                 #include "salve.h"
  4420.  
  4421.                 main()
  4422.                 {
  4423.                    struct UserRec *u;
  4424.                    Lnode  node1, node2;
  4425.                    Lroot  root;
  4426.  
  4427.                    /* open the list */
  4428.                       :   :   :
  4429.                    /* add records to the list */
  4430.                       :   :   :
  4431.  
  4432.                    /* find the first node with a given key *
  4433.                    node1 = Lfind (root, "Key Field", &u, FIND_EQ);
  4434.  
  4435.                    /* find the next node with the same key *
  4436.                    node2 = Lfind_next (root, node1, "Key Field", &u);
  4437.  
  4438.                    /* close the list */
  4439.                 }
  4440.  
  4441.  
  4442.  
  4443.  
  4444.  
  4445.  
  4446.  
  4447.  
  4448.  
  4449.  
  4450.  
  4451.  
  4452.  
  4453.  
  4454.  
  4455.  
  4456.  
  4457.  
  4458.  
  4459.  
  4460.  
  4461.  
  4462.  
  4463.  
  4464.  
  4465.  
  4466.  
  4467.  
  4468.  
  4469.  
  4470.  
  4471.  
  4472.  
  4473.  
  4474.  
  4475.  
  4476.                                           - 67 -
  4477.  
  4478.  
  4479.  
  4480.  
  4481.                                  Copyright Ron Albury 1988
  4482.  
  4483.           FUNCTION Lfind_node
  4484.                    Lfind_node
  4485.  
  4486.              PURPOSE
  4487.  
  4488.                 Finds the  data element  associated with  a list node.  This
  4489.              function is  useful if you store the list nodes in another data
  4490.              management structure (such as a hash table).
  4491.  
  4492.              PARAMETERS
  4493.  
  4494.                 Node:  (Input)
  4495.                    The list  node to  be used  in finding  the  requested
  4496.                    data.
  4497.  
  4498.                 Found: (Output)
  4499.                    The data element located at that node.
  4500.  
  4501.              RETURNS
  4502.  
  4503.                 void.
  4504.  
  4505.              PROTOTYPE
  4506.  
  4507.                 void Lfind_node
  4508.                    (Lnode node, void **found);
  4509.  
  4510.              DEBUG
  4511.  
  4512.                 The debug library (only) will report:
  4513.                    1) Null node.
  4514.                    2) Null found.
  4515.  
  4516.  
  4517.  
  4518.  
  4519.  
  4520.  
  4521.  
  4522.  
  4523.  
  4524.  
  4525.  
  4526.  
  4527.  
  4528.  
  4529.  
  4530.  
  4531.  
  4532.  
  4533.  
  4534.  
  4535.  
  4536.  
  4537.  
  4538.  
  4539.  
  4540.  
  4541.  
  4542.  
  4543.                                           - 68 -
  4544.  
  4545.  
  4546.  
  4547.  
  4548.                                  Copyright Ron Albury 1988
  4549.  
  4550.              EXAMPLE
  4551.  
  4552.                 #include "salve.h"
  4553.  
  4554.                 main()
  4555.                 {
  4556.                    struct UserRec *u;
  4557.                    Lnode  node;
  4558.                    Lroot  root;
  4559.  
  4560.                    /* open the list */
  4561.                       :   :   :
  4562.                    /* add records to the list */
  4563.                       :   :   :
  4564.                    /* cross reference them in a hash table */
  4565.                       :   :   :
  4566.  
  4567.                    /* find a node through the hash table *
  4568.                       :   :   :
  4569.  
  4570.                    /* get the data associated with it */
  4571.                    Lfind_node (node, &u);
  4572.  
  4573.                    /* delete the node from the list and the table */
  4574.                       :   :   :
  4575.  
  4576.                    /* close the list */
  4577.                 }
  4578.  
  4579.  
  4580.  
  4581.  
  4582.  
  4583.  
  4584.  
  4585.  
  4586.  
  4587.  
  4588.  
  4589.  
  4590.  
  4591.  
  4592.  
  4593.  
  4594.  
  4595.  
  4596.  
  4597.  
  4598.  
  4599.  
  4600.  
  4601.  
  4602.  
  4603.  
  4604.  
  4605.  
  4606.  
  4607.  
  4608.  
  4609.                                           - 69 -
  4610.  
  4611.  
  4612.  
  4613.  
  4614.                                  Copyright Ron Albury 1988
  4615.  
  4616.           FUNCTION Lmake_first
  4617.                    Lmake_first
  4618.  
  4619.              PURPOSE
  4620.  
  4621.                 Moves a  data element  from its current position in the list
  4622.              to the  first position.   This  function is more efficient than
  4623.              deleting a  node from  the middle  of the list and adding it at
  4624.              the head of the list.
  4625.  
  4626.              PARAMETERS
  4627.  
  4628.                 Root: (Input)
  4629.                    The root of the list being accessed.
  4630.  
  4631.                 Node: (Output)
  4632.                    The list node of the element to be moved.
  4633.  
  4634.              RETURNS
  4635.  
  4636.                 Integer indicating status of the move.
  4637.                    0 = Success.
  4638.                    1 = Corrupted memory, or indicated element is not part
  4639.                        of this list.
  4640.  
  4641.              PROTOTYPE
  4642.  
  4643.                 int Lmake_first
  4644.                    (Lroot root, Lnode node);
  4645.  
  4646.              DEBUG
  4647.  
  4648.                 The debug library (only) will report:
  4649.                    1) Null root.
  4650.                    2) Null node.
  4651.                    3) Internal consistency test.
  4652.  
  4653.  
  4654.  
  4655.  
  4656.  
  4657.  
  4658.  
  4659.  
  4660.  
  4661.  
  4662.  
  4663.  
  4664.  
  4665.  
  4666.  
  4667.  
  4668.  
  4669.  
  4670.  
  4671.  
  4672.  
  4673.  
  4674.  
  4675.  
  4676.                                           - 70 -
  4677.  
  4678.  
  4679.  
  4680.  
  4681.                                  Copyright Ron Albury 1988
  4682.  
  4683.              EXAMPLE
  4684.  
  4685.                 #include "salve.h"
  4686.  
  4687.                 main()
  4688.                 {
  4689.                    struct UserRec *u;
  4690.                    Lnode  node;
  4691.                    Lroot  root;
  4692.  
  4693.                    /* open the list */
  4694.                       :   :   :
  4695.                    /* add records to the list */
  4696.                       :   :   :
  4697.  
  4698.                    /* find the first node with a given key *
  4699.                    node = Lfind (root, "Key Field", &u, FIND_EQ);
  4700.  
  4701.                    /* make this (the most recently used node) first *
  4702.                    Lmake_first (root, node);
  4703.  
  4704.                    /* close the list */
  4705.                 }
  4706.  
  4707.  
  4708.  
  4709.  
  4710.  
  4711.  
  4712.  
  4713.  
  4714.  
  4715.  
  4716.  
  4717.  
  4718.  
  4719.  
  4720.  
  4721.  
  4722.  
  4723.  
  4724.  
  4725.  
  4726.  
  4727.  
  4728.  
  4729.  
  4730.  
  4731.  
  4732.  
  4733.  
  4734.  
  4735.  
  4736.  
  4737.  
  4738.  
  4739.  
  4740.  
  4741.  
  4742.                                           - 71 -
  4743.  
  4744.  
  4745.  
  4746.  
  4747.                                  Copyright Ron Albury 1988
  4748.  
  4749.           FUNCTION Lopen
  4750.                    Lopen
  4751.  
  4752.              PURPOSE
  4753.  
  4754.                 Opens  a   linked  list  and  creates  the  data  structures
  4755.              necessary for  it's management.  As with a file, each list must
  4756.              be opened before it can be used in your program.  This function
  4757.              is required  before any  other of  the list  operations can  be
  4758.              performed on the list.
  4759.  
  4760.                 If you  plan to perform  searches on the list based on a key
  4761.              field you  must associate  a key  comparison function  with the
  4762.              list when it is opened.
  4763.  
  4764.              PARAMETERS
  4765.  
  4766.                 Root: (Output)
  4767.                    The root  (or handle)  of the list being opened.  This
  4768.                    parameter is referenced by all other list functions.
  4769.  
  4770.                 Comp: (Input)
  4771.                    The comparison function to be used with this list (may
  4772.                    be NULL  if you  are not  ordering  you  list  by  key
  4773.                    values).   See the  introduction for  a description of
  4774.                    this function  and Lfind  for an  application of  this
  4775.                    function.
  4776.  
  4777.              RETURNS
  4778.  
  4779.                 An integer indicating the status of the call.
  4780.                    0 = Success.
  4781.  
  4782.              PROTOTYPE
  4783.  
  4784.                 int Lopen
  4785.                    (Lroot *root,  KCmpFnc comp);
  4786.  
  4787.              DEBUG
  4788.  
  4789.                 Both libraries will report:
  4790.                    1) Null root pointer.
  4791.                    2) Malloc failure.
  4792.  
  4793.  
  4794.  
  4795.  
  4796.  
  4797.  
  4798.  
  4799.  
  4800.  
  4801.  
  4802.  
  4803.  
  4804.  
  4805.  
  4806.  
  4807.  
  4808.  
  4809.                                           - 72 -
  4810.  
  4811.  
  4812.  
  4813.  
  4814.                                  Copyright Ron Albury 1988
  4815.  
  4816.              EXAMPLE
  4817.  
  4818.                 #include "salve.h"
  4819.  
  4820.                 int compare (void *data, void *key)
  4821.                 {  /* compare the data with the key */  }
  4822.  
  4823.                 main()
  4824.                 {
  4825.                    int   status;
  4826.                    Lroot root;
  4827.  
  4828.                    status = Lopen (&root, compare);
  4829.                       :   :   :
  4830.                 }
  4831.  
  4832.  
  4833.  
  4834.  
  4835.  
  4836.  
  4837.  
  4838.  
  4839.  
  4840.  
  4841.  
  4842.  
  4843.  
  4844.  
  4845.  
  4846.  
  4847.  
  4848.  
  4849.  
  4850.  
  4851.  
  4852.  
  4853.  
  4854.  
  4855.  
  4856.  
  4857.  
  4858.  
  4859.  
  4860.  
  4861.  
  4862.  
  4863.  
  4864.  
  4865.  
  4866.  
  4867.  
  4868.  
  4869.  
  4870.  
  4871.  
  4872.  
  4873.  
  4874.  
  4875.                                           - 73 -
  4876.  
  4877.  
  4878.  
  4879.  
  4880.                                  Copyright Ron Albury 1988
  4881.  
  4882.           FUNCTION Lremove
  4883.                    Lremove
  4884.  
  4885.              PURPOSE
  4886.  
  4887.                 Removes a node and data element from the indicated list.
  4888.  
  4889.              PARAMETERS
  4890.  
  4891.                 Root: (Input)
  4892.                    The root of the list being accessed.
  4893.  
  4894.                 Node: (Output)
  4895.                    The list node of the element to be removed.
  4896.  
  4897.              RETURNS
  4898.  
  4899.                 Integer indicating status of removal.
  4900.                    0 = Success.
  4901.                    1 = Corrupted memory, or indicated element is not part
  4902.                    of this list.
  4903.  
  4904.              PROTOTYPE
  4905.  
  4906.                 int Lremove
  4907.                    (Lroot root, Lnode node);
  4908.  
  4909.              DEBUG
  4910.  
  4911.                 The debug library (only) will report:
  4912.                    1) Null root.
  4913.                    2) Null node.
  4914.                    3) Internal consistency test.
  4915.  
  4916.  
  4917.  
  4918.  
  4919.  
  4920.  
  4921.  
  4922.  
  4923.  
  4924.  
  4925.  
  4926.  
  4927.  
  4928.  
  4929.  
  4930.  
  4931.  
  4932.  
  4933.  
  4934.  
  4935.  
  4936.  
  4937.  
  4938.  
  4939.  
  4940.  
  4941.  
  4942.                                           - 74 -
  4943.  
  4944.  
  4945.  
  4946.  
  4947.                                  Copyright Ron Albury 1988
  4948.  
  4949.              EXAMPLE
  4950.  
  4951.                 #include "salve.h"
  4952.  
  4953.                 main()
  4954.                 {
  4955.                    int    status;
  4956.                    struct UserRec *u;
  4957.                    Lnode  node;
  4958.                    Lroot  root;
  4959.  
  4960.                    /* open the list */
  4961.                    /* add records to the list */
  4962.                       :   :   :
  4963.  
  4964.                    /* find the first node with a given key *
  4965.                    node = Lfind (root, "Key Field", &u);
  4966.  
  4967.                    /* remove that node */
  4968.                    status = Lremove (root, node);
  4969.  
  4970.                       :   :   :
  4971.                 }
  4972.  
  4973.  
  4974.  
  4975.  
  4976.  
  4977.  
  4978.  
  4979.  
  4980.  
  4981.  
  4982.  
  4983.  
  4984.  
  4985.  
  4986.  
  4987.  
  4988.  
  4989.  
  4990.  
  4991.  
  4992.  
  4993.  
  4994.  
  4995.  
  4996.  
  4997.  
  4998.  
  4999.  
  5000.  
  5001.  
  5002.  
  5003.  
  5004.  
  5005.  
  5006.  
  5007.  
  5008.                                           - 75 -
  5009.  
  5010.  
  5011.  
  5012.  
  5013.                                  Copyright Ron Albury 1988
  5014.  
  5015.           FUNCTION Ltest
  5016.                    Ltest
  5017.  
  5018.              PURPOSE
  5019.  
  5020.                 Tests a  list node to detect memory corruption and to verify
  5021.              that the node is from the indicated list.
  5022.  
  5023.              PARAMETERS
  5024.  
  5025.                 Root: (Input)
  5026.                    The root of the list being accessed.
  5027.  
  5028.                 Node: (Output)
  5029.                    The node to be tested.
  5030.  
  5031.              RETURNS
  5032.  
  5033.                 Integer indicating status of test.
  5034.                    0 = Success.
  5035.                    1 = Corrupted memory, or indicated element is not part
  5036.                        of this list.
  5037.  
  5038.              PROTOTYPE
  5039.  
  5040.                 int Ltest
  5041.                    (Lroot root, Lnode node);
  5042.  
  5043.              DEBUG
  5044.  
  5045.                 The debug library (only) will report:
  5046.                    1) Null root.
  5047.                    2) Null node.
  5048.  
  5049.  
  5050.  
  5051.  
  5052.  
  5053.  
  5054.  
  5055.  
  5056.  
  5057.  
  5058.  
  5059.  
  5060.  
  5061.  
  5062.  
  5063.  
  5064.  
  5065.  
  5066.  
  5067.  
  5068.  
  5069.  
  5070.  
  5071.  
  5072.  
  5073.  
  5074.  
  5075.                                           - 76 -
  5076.  
  5077.  
  5078.  
  5079.  
  5080.                                  Copyright Ron Albury 1988
  5081.  
  5082.              EXAMPLE
  5083.  
  5084.                 #include "salve.h"
  5085.  
  5086.                 main()
  5087.                 {
  5088.                    int    status;
  5089.                    struct UserRec *u;
  5090.                    Lnode  node;
  5091.                    Lroot  root;
  5092.  
  5093.                    /* open the list */
  5094.                    /* add records to the list */
  5095.                       :   :   :
  5096.  
  5097.                    /* find the first node with a given key *
  5098.                    node = Lfind (root, "Key Field", &u);
  5099.  
  5100.                    /* test that node for corruption */
  5101.                    status = Ltest (root, node);
  5102.  
  5103.                       :   :   :
  5104.                 }
  5105.  
  5106.  
  5107.  
  5108.  
  5109.  
  5110.  
  5111.  
  5112.  
  5113.  
  5114.  
  5115.  
  5116.  
  5117.  
  5118.  
  5119.  
  5120.  
  5121.  
  5122.  
  5123.  
  5124.  
  5125.  
  5126.  
  5127.  
  5128.  
  5129.  
  5130.  
  5131.  
  5132.  
  5133.  
  5134.  
  5135.  
  5136.  
  5137.  
  5138.  
  5139.  
  5140.  
  5141.                                           - 77 -
  5142.  
  5143.  
  5144.  
  5145.  
  5146.                                  Copyright Ron Albury 1988
  5147.  
  5148.           SPARSE MATRIX CLASS
  5149.           SPARSE MATRIX CLASS
  5150.  
  5151.                 Probably the easiest analogy for a sparse matrix is a spread
  5152.              sheet.   You have lots of potential places to put data, but you
  5153.              only use  a few  of them.  Rather than allocate a huge array of
  5154.              record structures  (or even  a  slightly  less  huge  array  of
  5155.              pointers to  record structures)  you  may  want  to  use  these
  5156.              routines.
  5157.  
  5158.                 The following functions allow you to have as many dimensions
  5159.              in the  array as  you want.   It's  only limitation is that you
  5160.              have some  idea of  how many elements will eventually end up in
  5161.              the matrix.
  5162.  
  5163.                 A matrix  is a  good tool whenever you have lots of data you
  5164.              need to  access based on multiple numeric keys.  You could, for
  5165.              instance, use  height, weight, and age for the three dimensions
  5166.              of the  matrix, and  have the  entry be  a list of all children
  5167.              that fall  into that  category.   This would be accomplished by
  5168.              storing in the matrix the root of a list.
  5169.  
  5170.                 There are many other ways to implement a sparse matrix, some
  5171.              of which  may be  faster for your application.  These functions
  5172.              are included  to provide  a full  set of  capability within the
  5173.              Salve Data  Management  functions,  and  to  provide  a  common
  5174.              interface for you should you need a sparse matrix.
  5175.  
  5176.  
  5177.  
  5178.  
  5179.  
  5180.  
  5181.  
  5182.  
  5183.  
  5184.  
  5185.  
  5186.  
  5187.  
  5188.  
  5189.  
  5190.  
  5191.  
  5192.  
  5193.  
  5194.  
  5195.  
  5196.  
  5197.  
  5198.  
  5199.  
  5200.  
  5201.  
  5202.  
  5203.  
  5204.  
  5205.  
  5206.  
  5207.  
  5208.                                           - 78 -
  5209.  
  5210.  
  5211.  
  5212.  
  5213.                                  Copyright Ron Albury 1988
  5214.  
  5215.           FUNCTION Madd
  5216.                    Madd
  5217.  
  5218.              PURPOSE
  5219.  
  5220.                 Adds an element to the appropriate cell of the matrix.
  5221.  
  5222.              PARAMETERS
  5223.  
  5224.                 Root: (Input)
  5225.                    The root of the matrix being accessed.
  5226.  
  5227.                 Data: (Input)
  5228.                    The element to be placed into the matrix.
  5229.  
  5230.                 Indx: (Input)
  5231.                    The index  of the  matrix to place this element.  This
  5232.                    is  a  list  of  integers  (one  for  each  dimension)
  5233.                    indicating row, column, etc.
  5234.  
  5235.              RETURNS
  5236.  
  5237.                 Matrix node of the added element.
  5238.  
  5239.              PROTOTYPE
  5240.  
  5241.                 Mnode Madd
  5242.                    (Mroot root, void *data, ...);
  5243.  
  5244.              DEBUG
  5245.  
  5246.                 The debug library (only) will report:
  5247.                    1) Null root.
  5248.                    2) Null data.
  5249.                    3) Malloc failure.
  5250.  
  5251.  
  5252.  
  5253.  
  5254.  
  5255.  
  5256.  
  5257.  
  5258.  
  5259.  
  5260.  
  5261.  
  5262.  
  5263.  
  5264.  
  5265.  
  5266.  
  5267.  
  5268.  
  5269.  
  5270.  
  5271.  
  5272.  
  5273.  
  5274.  
  5275.                                           - 79 -
  5276.  
  5277.  
  5278.  
  5279.  
  5280.                                  Copyright Ron Albury 1988
  5281.  
  5282.              EXAMPLE
  5283.  
  5284.                 #include "salve.h"
  5285.  
  5286.                 main()
  5287.                 {
  5288.                    struct UserRec *u;
  5289.                    char   key[32];
  5290.                    Mnode  node;
  5291.                    Mroot  root;
  5292.  
  5293.                    /* open the matrix */
  5294.                       :   :   :
  5295.  
  5296.                    /* create a new data element for the matrix */
  5297.                    u = malloc(sizeof(struct UserRec));
  5298.  
  5299.                    /* assign values to the new data element */
  5300.                    gets (key);
  5301.                    assign_values(u, key);
  5302.  
  5303.                    /* add the new data to the matrix */
  5304.                    node = Madd (root, u, 3, 5, 2, 1);
  5305.  
  5306.                    /* use the matrix */
  5307.                       :   :   :
  5308.  
  5309.                    /* close the matrix */
  5310.  
  5311.                 }
  5312.  
  5313.  
  5314.  
  5315.  
  5316.  
  5317.  
  5318.  
  5319.  
  5320.  
  5321.  
  5322.  
  5323.  
  5324.  
  5325.  
  5326.  
  5327.  
  5328.  
  5329.  
  5330.  
  5331.  
  5332.  
  5333.  
  5334.  
  5335.  
  5336.  
  5337.  
  5338.  
  5339.  
  5340.  
  5341.                                           - 80 -
  5342.  
  5343.  
  5344.  
  5345.  
  5346.                                  Copyright Ron Albury 1988
  5347.  
  5348.           FUNCTION Mcard
  5349.                    Mcard
  5350.  
  5351.              PURPOSE
  5352.  
  5353.                 Returns the cardinality (number of elements) of the matrix.
  5354.  
  5355.              PARAMETERS
  5356.  
  5357.                 Root: (Input)
  5358.                    The root of the matrix being accessed.
  5359.  
  5360.              RETURNS
  5361.  
  5362.                 Long integer  indicating number of elements currently in the
  5363.              matrix.
  5364.  
  5365.              PROTOTYPE
  5366.  
  5367.                 long Mcard
  5368.                    (Mroot root);
  5369.  
  5370.              DEBUG
  5371.  
  5372.                 The debug library (only) will report:
  5373.                    1) Null root.
  5374.  
  5375.              EXAMPLE
  5376.  
  5377.                 #include "salve.h"
  5378.  
  5379.                 main()
  5380.                 {
  5381.                    Mroot  root;
  5382.                    long    quan;
  5383.  
  5384.                    /* open the matrix */
  5385.                       :   :   :
  5386.  
  5387.                    /* use the matrix */
  5388.                       :   :   :
  5389.  
  5390.                    /* find out how elements are in the matrix */
  5391.                    quan = Mcard (root);
  5392.  
  5393.                    /* close the matrix */
  5394.                 }
  5395.  
  5396.  
  5397.  
  5398.  
  5399.  
  5400.  
  5401.  
  5402.  
  5403.  
  5404.  
  5405.  
  5406.  
  5407.  
  5408.                                           - 81 -
  5409.  
  5410.  
  5411.  
  5412.  
  5413.                                  Copyright Ron Albury 1988
  5414.  
  5415.           FUNCTION Mclose
  5416.                    Mclose
  5417.  
  5418.              PURPOSE
  5419.  
  5420.                 Closes a  previously opened  matrix.  All elements must have
  5421.              been removed from the matrix before the matrix is closed.
  5422.  
  5423.              PARAMETERS
  5424.  
  5425.                 Root: (Input/Output)
  5426.                    The root of the matrix being closed.
  5427.  
  5428.              RETURNS
  5429.  
  5430.                 Integer indicating status of the close.
  5431.                    0 = Success.
  5432.                    1 = Elements were left in the matrix.  Remove them and
  5433.                        try again.
  5434.  
  5435.              PROTOTYPE
  5436.  
  5437.                 int Mclose
  5438.                    (Mroot *root);
  5439.  
  5440.              DEBUG
  5441.  
  5442.                 The debug library (only) will report:
  5443.                    1) Null root pointer.
  5444.  
  5445.              EXAMPLE
  5446.  
  5447.                 #include "salve.h"
  5448.  
  5449.                 main()
  5450.                 {
  5451.                    int   status;
  5452.                    Mroot root;
  5453.  
  5454.                    /* open the matrix */
  5455.                    /* use the matrix */
  5456.                       :   :   :
  5457.                    status = Mclose (&root);
  5458.                 }
  5459.  
  5460.  
  5461.  
  5462.  
  5463.  
  5464.  
  5465.  
  5466.  
  5467.  
  5468.  
  5469.  
  5470.  
  5471.  
  5472.  
  5473.  
  5474.  
  5475.                                           - 82 -
  5476.  
  5477.  
  5478.  
  5479.  
  5480.                                  Copyright Ron Albury 1988
  5481.  
  5482.           FUNCTION Mfind
  5483.                    Mfind
  5484.  
  5485.              PURPOSE
  5486.  
  5487.                 Finds an element in the indicated matrix.
  5488.  
  5489.              PARAMETERS
  5490.  
  5491.                 Root:  (Input)
  5492.                    The root of the matrix being accessed.
  5493.  
  5494.                 Found: (Output)
  5495.                    The element  in the  matrix which  is at the indicated
  5496.                    location.
  5497.  
  5498.                 Indx:  (Input)
  5499.                    The index  of the matrix to locate this element.  This
  5500.                    is  a  list  of  integers  (one  for  each  dimension)
  5501.                    indicating row, column, etc.
  5502.  
  5503.              RETURNS
  5504.  
  5505.                 A Mnode pointer
  5506.                    Success: Matrix node of the found element.
  5507.                    Failure: NULL (no element at that index)
  5508.  
  5509.              PROTOTYPE
  5510.  
  5511.                 Mnode Mfind
  5512.                    (Mroot root, void **found, ...);
  5513.  
  5514.              DEBUG
  5515.  
  5516.                 The debug library (only) will report:
  5517.                    1) Null root.
  5518.                    2) Null found.
  5519.                    3) Malloc failure.
  5520.                    4) Internal consistency check.
  5521.  
  5522.  
  5523.  
  5524.  
  5525.  
  5526.  
  5527.  
  5528.  
  5529.  
  5530.  
  5531.  
  5532.  
  5533.  
  5534.  
  5535.  
  5536.  
  5537.  
  5538.  
  5539.  
  5540.  
  5541.  
  5542.                                           - 83 -
  5543.  
  5544.  
  5545.  
  5546.  
  5547.                                  Copyright Ron Albury 1988
  5548.  
  5549.              EXAMPLE
  5550.  
  5551.                 #include "salve.h"
  5552.  
  5553.                 main()
  5554.                 {
  5555.                    struct UserRec *u;
  5556.                    Mnode  node;
  5557.                    Mroot  root;
  5558.  
  5559.                    /* open the matrix */
  5560.                    /* add records to the matrix */
  5561.                       :   :   :
  5562.  
  5563.                    /* find a node in the matrix *
  5564.                    gets (key)
  5565.                    node = Mfind (root, &u, 6, 4, 18, 49);
  5566.  
  5567.                    /* use the matrix */
  5568.                       :   :   :
  5569.  
  5570.                    /* close the matrix */
  5571.                 }
  5572.  
  5573.  
  5574.  
  5575.  
  5576.  
  5577.  
  5578.  
  5579.  
  5580.  
  5581.  
  5582.  
  5583.  
  5584.  
  5585.  
  5586.  
  5587.  
  5588.  
  5589.  
  5590.  
  5591.  
  5592.  
  5593.  
  5594.  
  5595.  
  5596.  
  5597.  
  5598.  
  5599.  
  5600.  
  5601.  
  5602.  
  5603.  
  5604.  
  5605.  
  5606.  
  5607.  
  5608.                                           - 84 -
  5609.  
  5610.  
  5611.  
  5612.  
  5613.                                  Copyright Ron Albury 1988
  5614.  
  5615.           FUNCTION Mfind_node
  5616.                    Mfind_node
  5617.  
  5618.              PURPOSE
  5619.  
  5620.                 Finds the  data element associated with a matrix node.  This
  5621.              function is  useful if  you store  the matrix  nodes in another
  5622.              data management structure (such as a hash table).
  5623.  
  5624.              PARAMETERS
  5625.  
  5626.                 Node:  (Input)
  5627.                    The matrix  node to  be used  in finding the requested
  5628.                    data.
  5629.  
  5630.                 Found: (Output)
  5631.                    The data element located at that node.
  5632.  
  5633.              RETURNS
  5634.  
  5635.                 void.
  5636.  
  5637.              PROTOTYPE
  5638.  
  5639.                 void Mfind_node
  5640.                    (Mnode node, void **found);
  5641.  
  5642.              DEBUG
  5643.  
  5644.                 The debug library (only) will report:
  5645.                    1) Null node.
  5646.                    2) Null found.
  5647.  
  5648.  
  5649.  
  5650.  
  5651.  
  5652.  
  5653.  
  5654.  
  5655.  
  5656.  
  5657.  
  5658.  
  5659.  
  5660.  
  5661.  
  5662.  
  5663.  
  5664.  
  5665.  
  5666.  
  5667.  
  5668.  
  5669.  
  5670.  
  5671.  
  5672.  
  5673.  
  5674.  
  5675.                                           - 85 -
  5676.  
  5677.  
  5678.  
  5679.  
  5680.                                  Copyright Ron Albury 1988
  5681.  
  5682.              EXAMPLE
  5683.  
  5684.                 #include "salve.h"
  5685.  
  5686.                 main()
  5687.                 {
  5688.                    struct UserRec *u;
  5689.                    Mnode  node;
  5690.                    Mroot  root;
  5691.  
  5692.                    /* open the matrix */
  5693.                    /* add records to the matrix */
  5694.                    /* cross reference them in a hash table */
  5695.                       :   :   :
  5696.  
  5697.                    /* find a node through the hash table *
  5698.                       :   :   :
  5699.  
  5700.                    /* get the data associated with it */
  5701.                    Mfind_node (node, &u);
  5702.  
  5703.                    /* delete the node from the matrix and the table */
  5704.                       :   :   :
  5705.  
  5706.                    /* close the matrix */
  5707.                 }
  5708.  
  5709.  
  5710.  
  5711.  
  5712.  
  5713.  
  5714.  
  5715.  
  5716.  
  5717.  
  5718.  
  5719.  
  5720.  
  5721.  
  5722.  
  5723.  
  5724.  
  5725.  
  5726.  
  5727.  
  5728.  
  5729.  
  5730.  
  5731.  
  5732.  
  5733.  
  5734.  
  5735.  
  5736.  
  5737.  
  5738.  
  5739.  
  5740.  
  5741.                                           - 86 -
  5742.  
  5743.  
  5744.  
  5745.  
  5746.                                  Copyright Ron Albury 1988
  5747.  
  5748.           FUNCTION Mopen
  5749.                    Mopen
  5750.  
  5751.              PURPOSE
  5752.  
  5753.                 Opens a  sparse  matrix  and  creates  the  data  structures
  5754.              necessary for  its management.   As  with Lopen,  you must call
  5755.              this function  for each  matrix to  be used.   This function is
  5756.              required before  any other  of  the  matrix  functions  can  be
  5757.              performed.   A matrix  can be  used to index a linked list (the
  5758.              data item  stored in  the matrix  is the link node) or to store
  5759.              data directly.   Any matrix of known size with more than 1/2 of
  5760.              the cells  filled should  consider using  a  multi  dimensional
  5761.              array of  records (or  of pointers to records) instead of these
  5762.              sparse matrix routines.
  5763.  
  5764.              PARAMETERS
  5765.  
  5766.                 Root: (Output)
  5767.                    The root  (or handle)  of  the  matrix  being  opened.
  5768.                    Referenced by all other matrix functions.
  5769.  
  5770.                 Dim:  (Input)
  5771.                    The number of dimensions to use for this matrix.
  5772.  
  5773.                 Quan: (Input)
  5774.                    Estimated number  of elements  to  be  stored  in  the
  5775.                    matrix (+ or - 25% - too few slows down/too many takes
  5776.                    up space).
  5777.  
  5778.              RETURNS
  5779.  
  5780.                 Integer indicating status of the open.
  5781.                    0 = Success.
  5782.  
  5783.              PROTOTYPE
  5784.  
  5785.                 int Mopen
  5786.                    (Mroot *root, unsigned dim, unsigned quan);
  5787.  
  5788.              DEBUG
  5789.  
  5790.                 Both libraries will report:
  5791.                    1) Null root pointer.
  5792.                    2) Too few dimensions.
  5793.                    3) Small quantity.
  5794.                    4) Malloc failure.
  5795.  
  5796.  
  5797.  
  5798.  
  5799.  
  5800.  
  5801.  
  5802.  
  5803.  
  5804.  
  5805.  
  5806.  
  5807.  
  5808.                                           - 87 -
  5809.  
  5810.  
  5811.  
  5812.  
  5813.                                  Copyright Ron Albury 1988
  5814.  
  5815.              EXAMPLE
  5816.  
  5817.                 #include "salve.h"
  5818.                 main()
  5819.                 {
  5820.                    int   status;
  5821.                    Mroot root;
  5822.  
  5823.                    /* open a four dimensional sparse matrix
  5824.                       to hold approximately 100 elements    */
  5825.                    status = Mopen (&root, 4, 100);
  5826.                       :   :   :
  5827.                 }
  5828.  
  5829.  
  5830.  
  5831.  
  5832.  
  5833.  
  5834.  
  5835.  
  5836.  
  5837.  
  5838.  
  5839.  
  5840.  
  5841.  
  5842.  
  5843.  
  5844.  
  5845.  
  5846.  
  5847.  
  5848.  
  5849.  
  5850.  
  5851.  
  5852.  
  5853.  
  5854.  
  5855.  
  5856.  
  5857.  
  5858.  
  5859.  
  5860.  
  5861.  
  5862.  
  5863.  
  5864.  
  5865.  
  5866.  
  5867.  
  5868.  
  5869.  
  5870.  
  5871.  
  5872.  
  5873.  
  5874.                                           - 88 -
  5875.  
  5876.  
  5877.  
  5878.  
  5879.                                  Copyright Ron Albury 1988
  5880.  
  5881.           FUNCTION Mremove
  5882.                    Mremove
  5883.  
  5884.              PURPOSE
  5885.  
  5886.                 Removes a node and data element from the indicated matrix.
  5887.  
  5888.              PARAMETERS
  5889.  
  5890.                 Root: (Input)
  5891.                    The root of the matrix being accessed.
  5892.  
  5893.                 Node: (Input)
  5894.                    The matrix node of the element to remove.
  5895.  
  5896.              RETURNS
  5897.  
  5898.                 Integer indicating status of the removal.
  5899.                    0 = Success.
  5900.                    1 = Corrupted memory, or indicated element is not part
  5901.                        of this matrix.
  5902.  
  5903.              PROTOTYPE
  5904.  
  5905.                 int Mremove
  5906.                    (Mroot root, Mnode node);
  5907.  
  5908.              DEBUG
  5909.  
  5910.                 The debug library (only) will report:
  5911.                    1) Null root.
  5912.                    2) Null node.
  5913.  
  5914.  
  5915.  
  5916.  
  5917.  
  5918.  
  5919.  
  5920.  
  5921.  
  5922.  
  5923.  
  5924.  
  5925.  
  5926.  
  5927.  
  5928.  
  5929.  
  5930.  
  5931.  
  5932.  
  5933.  
  5934.  
  5935.  
  5936.  
  5937.  
  5938.  
  5939.  
  5940.  
  5941.                                           - 89 -
  5942.  
  5943.  
  5944.  
  5945.  
  5946.                                  Copyright Ron Albury 1988
  5947.  
  5948.              EXAMPLE
  5949.  
  5950.                 #include "salve.h"
  5951.  
  5952.                 main()
  5953.                 {
  5954.                    struct UserRec *u;
  5955.                    Mnode  node;
  5956.                    Mroot  root;
  5957.  
  5958.                    /* open the matrix */
  5959.                    /* add records to the matrix */
  5960.                       :   :   :
  5961.  
  5962.                    /* find a node in the matrix *
  5963.                    gets (key)
  5964.                    node = Mfind (root, &u, 55, 32, 47);
  5965.  
  5966.                    /* delete that node */
  5967.                    Mremove (root, node)
  5968.  
  5969.                    /* use the matrix */
  5970.                       :   :   :
  5971.  
  5972.                    /* close the matrix */
  5973.                 }
  5974.  
  5975.  
  5976.  
  5977.  
  5978.  
  5979.  
  5980.  
  5981.  
  5982.  
  5983.  
  5984.  
  5985.  
  5986.  
  5987.  
  5988.  
  5989.  
  5990.  
  5991.  
  5992.  
  5993.  
  5994.  
  5995.  
  5996.  
  5997.  
  5998.  
  5999.  
  6000.  
  6001.  
  6002.  
  6003.  
  6004.  
  6005.  
  6006.  
  6007.                                           - 90 -
  6008.  
  6009.  
  6010.  
  6011.  
  6012.                                  Copyright Ron Albury 1988
  6013.  
  6014.           FUNCTION Mtest
  6015.                    Mtest
  6016.  
  6017.              PURPOSE
  6018.  
  6019.                 Tests a matrix node to detect memory corruption or to verify
  6020.              that the element is from the indicated matrix.
  6021.  
  6022.              PARAMETERS
  6023.  
  6024.                 Root: (Input)
  6025.                    The root of the matrix being accessed.
  6026.  
  6027.                 Node: (Input)
  6028.                    The matrix node to be tested.
  6029.  
  6030.              RETURNS
  6031.  
  6032.                 Integer indicating status of the test.
  6033.                    0 = Success.
  6034.                    1 = Corrupted memory, or indicated element is not part
  6035.                        of this matrix.
  6036.  
  6037.              PROTOTYPE
  6038.  
  6039.                 int Mtest
  6040.                    (Mroot root, Mnode node);
  6041.  
  6042.              DEBUG
  6043.  
  6044.                 The debug library (only) will report:
  6045.                    1) Null root.
  6046.                    2) Null node.
  6047.  
  6048.  
  6049.  
  6050.  
  6051.  
  6052.  
  6053.  
  6054.  
  6055.  
  6056.  
  6057.  
  6058.  
  6059.  
  6060.  
  6061.  
  6062.  
  6063.  
  6064.  
  6065.  
  6066.  
  6067.  
  6068.  
  6069.  
  6070.  
  6071.  
  6072.  
  6073.  
  6074.                                           - 91 -
  6075.  
  6076.  
  6077.  
  6078.  
  6079.                                  Copyright Ron Albury 1988
  6080.  
  6081.              EXAMPLE
  6082.  
  6083.                 #include "salve.h"
  6084.  
  6085.                 main()
  6086.                 {
  6087.                    int    status;
  6088.                    struct UserRec *u;
  6089.                    Mnode  node;
  6090.                    Mroot  root;
  6091.  
  6092.                    /* open the matrix */
  6093.                    /* add records to the matrix */
  6094.                       :   :   :
  6095.  
  6096.                    /* find a node in the matrix */
  6097.                    node = Mfind_first (root, &u, 88, 74, 32);
  6098.  
  6099.                    /* test that node for corruption */
  6100.                    status = Mtest (root, node);
  6101.  
  6102.                       :   :   :
  6103.                 }
  6104.  
  6105.  
  6106.  
  6107.  
  6108.  
  6109.  
  6110.  
  6111.  
  6112.  
  6113.  
  6114.  
  6115.  
  6116.  
  6117.  
  6118.  
  6119.  
  6120.  
  6121.  
  6122.  
  6123.  
  6124.  
  6125.  
  6126.  
  6127.  
  6128.  
  6129.  
  6130.  
  6131.  
  6132.  
  6133.  
  6134.  
  6135.  
  6136.  
  6137.  
  6138.  
  6139.  
  6140.                                           - 92 -
  6141.  
  6142.  
  6143.  
  6144.  
  6145.                                  Copyright Ron Albury 1988
  6146.  
  6147.           BINARY TREE CLASS
  6148.           BINARY TREE CLASS
  6149.  
  6150.                 Binary trees  are probably  the most  common tool  to  store
  6151.              keyed data,  especially if you need to access the data based on
  6152.              the order of the keys.  They provide fast access (relative to a
  6153.              sequential search),  and can  grow to  any size.  However, they
  6154.              are not  as fast  as hashing,  and can searching can degrade to
  6155.              worse than sequential search speed if the elements are added to
  6156.              the tree  in order.  Trees work best if the records are entered
  6157.              in random order.
  6158.  
  6159.                 It is  possible to  perform transforms on the tree while you
  6160.              are entering  data to  'balance' a  tree.   This will avoid the
  6161.              degradation from in-order entry.  However, balancing a tree can
  6162.              take quite  a bit  of work   It is usually inappropriate unless
  6163.              you plan  to build  a tree  and then leave it static except for
  6164.              look-ups.   Also, a  balanced tree  does not always provide the
  6165.              best  look-up   performance.    Ideally,  the  most  frequently
  6166.              accesses nodes of the tree would be closest to the top.  In the
  6167.              case of  a 'static'  tree you  are better  off loading the tree
  6168.              based on  frequency of  use  than  having  a  behind-the-scenes
  6169.              algorithm balance the tree for you.
  6170.  
  6171.                 The routines  provided here are just plain old binary trees.
  6172.              There is  no balancing,  and there is no adjustment of the tree
  6173.              based on frequency of use.
  6174.  
  6175.  
  6176.  
  6177.  
  6178.  
  6179.  
  6180.  
  6181.  
  6182.  
  6183.  
  6184.  
  6185.  
  6186.  
  6187.  
  6188.  
  6189.  
  6190.  
  6191.  
  6192.  
  6193.  
  6194.  
  6195.  
  6196.  
  6197.  
  6198.  
  6199.  
  6200.  
  6201.  
  6202.  
  6203.  
  6204.  
  6205.  
  6206.  
  6207.                                           - 93 -
  6208.  
  6209.  
  6210.  
  6211.  
  6212.                                  Copyright Ron Albury 1988
  6213.  
  6214.           FUNCTION Tadd
  6215.                    Tadd
  6216.  
  6217.              PURPOSE
  6218.  
  6219.                 Adds a  data element  to the appropriate branch of the tree.
  6220.              Duplicate entries are not permitted.
  6221.  
  6222.              PARAMETERS
  6223.  
  6224.                 Root: (Input)
  6225.                    The root of the tree being accessed.
  6226.  
  6227.                 Data: (Input)
  6228.                    The data element to be placed into the tree.
  6229.  
  6230.                 Key: (Input)
  6231.                    The key  field to  pass to  the compare  function  for
  6232.                    determining the  location in  the tree  for  the  data
  6233.                    element.   This field  may be  a pointer  to the  data
  6234.                    element, a pointer to a record of the same type as the
  6235.                    data element,  or it  may be  a pointer  to some other
  6236.                    structure (e.g just a field of the data element record
  6237.                    structure).
  6238.  
  6239.              RETURNS
  6240.  
  6241.                 A Tnode pointer
  6242.                    Success: Tree node of the added element.
  6243.                    Failure: NULL (duplicate entry found).
  6244.  
  6245.              PROTOTYPE
  6246.  
  6247.                 Tnode Tadd
  6248.                    (Troot troot, void *data, void *key);
  6249.  
  6250.              DEBUG
  6251.  
  6252.                 The debug library (only) will report:
  6253.                    1) Null root.
  6254.                    2) Null data.
  6255.                    3) Null key.
  6256.                    4) Malloc failure.
  6257.  
  6258.  
  6259.  
  6260.  
  6261.  
  6262.  
  6263.  
  6264.  
  6265.  
  6266.  
  6267.  
  6268.  
  6269.  
  6270.  
  6271.  
  6272.  
  6273.  
  6274.                                           - 94 -
  6275.  
  6276.  
  6277.  
  6278.  
  6279.                                  Copyright Ron Albury 1988
  6280.  
  6281.              EXAMPLE
  6282.  
  6283.                 #include "salve.h"
  6284.  
  6285.                 main()
  6286.                 {
  6287.                    struct UserRec *u;
  6288.                    char   key[32];
  6289.                    Tnode  node;
  6290.                    Troot  root;
  6291.  
  6292.                    /* open the tree */
  6293.                       :   :   :
  6294.  
  6295.                    /* create a new data element for the tree */
  6296.                    u = malloc(sizeof(struct UserRec));
  6297.  
  6298.                    /* assign values to the new data element */
  6299.                    gets (key);
  6300.                    assign_values(u, key);
  6301.  
  6302.                    /* add the new data to the tree */
  6303.                    node = Tadd (root, u, key);
  6304.  
  6305.                    /* use the tree */
  6306.                       :   :   :
  6307.  
  6308.                    /* close the tree */
  6309.  
  6310.                 }
  6311.  
  6312.  
  6313.  
  6314.  
  6315.  
  6316.  
  6317.  
  6318.  
  6319.  
  6320.  
  6321.  
  6322.  
  6323.  
  6324.  
  6325.  
  6326.  
  6327.  
  6328.  
  6329.  
  6330.  
  6331.  
  6332.  
  6333.  
  6334.  
  6335.  
  6336.  
  6337.  
  6338.  
  6339.  
  6340.                                           - 95 -
  6341.  
  6342.  
  6343.  
  6344.  
  6345.                                  Copyright Ron Albury 1988
  6346.  
  6347.           FUNCTION Tcard
  6348.                    Tcard
  6349.  
  6350.              PURPOSE
  6351.  
  6352.                 Returns the cardinality (number of elements) of the tree.
  6353.  
  6354.              PARAMETERS
  6355.  
  6356.                 Root: (Input)
  6357.                    The root of the tree being accessed.
  6358.  
  6359.              RETURNS
  6360.  
  6361.                 Long integer  indicating number of elements currently in the
  6362.              tree.
  6363.  
  6364.              PROTOTYPE
  6365.  
  6366.                 long Tcard
  6367.                    (Troot root);
  6368.  
  6369.              DEBUG
  6370.  
  6371.                 The debug library (only) will report:
  6372.                    1) Null root.
  6373.  
  6374.              EXAMPLE
  6375.  
  6376.                 #include "salve.h"
  6377.  
  6378.                 main()
  6379.                 {
  6380.                    Troot  root;
  6381.                    long   quan;
  6382.  
  6383.                    /* open the tree */
  6384.                       :   :   :
  6385.  
  6386.                    /* use the tree */
  6387.                       :   :   :
  6388.  
  6389.                    /* find out how elements are in the tree */
  6390.                    quan = Tcard (root);
  6391.  
  6392.                    /* close the tree */
  6393.                 }
  6394.  
  6395.  
  6396.  
  6397.  
  6398.  
  6399.  
  6400.  
  6401.  
  6402.  
  6403.  
  6404.  
  6405.  
  6406.  
  6407.                                           - 96 -
  6408.  
  6409.  
  6410.  
  6411.  
  6412.                                  Copyright Ron Albury 1988
  6413.  
  6414.           FUNCTION Tclose
  6415.                    Tclose
  6416.  
  6417.              PURPOSE
  6418.  
  6419.                 Closes a  previously  opened  tree.    All  nodes  and  data
  6420.              elements must  have been  removed from the tree before the tree
  6421.              is closed.
  6422.  
  6423.              PARAMETERS
  6424.  
  6425.                 Root: (Input/Output)
  6426.                    The root of the tree being closed.
  6427.  
  6428.              RETURNS
  6429.  
  6430.                 Integer indicating status of close.
  6431.                    0 = Success.
  6432.                    1 =  Elements were  left in the tree.  Remove them and
  6433.                        try again.
  6434.  
  6435.              PROTOTYPE
  6436.  
  6437.                 int Tclose (Troot *root);
  6438.  
  6439.              DEBUG
  6440.  
  6441.                 Both libraries will report:
  6442.                    1) Null root.
  6443.                    2) Internal consistency test.
  6444.  
  6445.              EXAMPLE
  6446.  
  6447.                 #include "salve.h"
  6448.  
  6449.                 main()
  6450.                 {
  6451.                    int   status;
  6452.                    Troot root;
  6453.  
  6454.                    /* open the tree */
  6455.                    /* use the tree */
  6456.                       :   :   :
  6457.                    status = Tclose (&root);
  6458.                 }
  6459.  
  6460.  
  6461.  
  6462.  
  6463.  
  6464.  
  6465.  
  6466.  
  6467.  
  6468.  
  6469.  
  6470.  
  6471.  
  6472.  
  6473.  
  6474.                                           - 97 -
  6475.  
  6476.  
  6477.  
  6478.  
  6479.                                  Copyright Ron Albury 1988
  6480.  
  6481.           FUNCTION Tfind
  6482.                    Tfind
  6483.  
  6484.              PURPOSE
  6485.  
  6486.                 Finds an element in the indicated tree.
  6487.  
  6488.              PARAMETERS
  6489.  
  6490.                 Root:  (Input)
  6491.                    The root of the tree being accessed.
  6492.  
  6493.                 Key:   (Input)
  6494.                    The key  field which is passed to the compare function
  6495.                    for selecting the tree element.
  6496.  
  6497.                 Found: (Output)
  6498.                    The element in the tree which matches the key.
  6499.  
  6500.              RETURNS
  6501.  
  6502.                 A Tnode pointer
  6503.                    Success: Tree node of the found element.
  6504.                    Failure: NULL (entry not found)
  6505.  
  6506.              PROTOTYPE
  6507.  
  6508.                 Tnode Tfind
  6509.                    (Troot troot, void *key, void **found);
  6510.  
  6511.              DEBUG
  6512.  
  6513.                 The debug library (only) will report:
  6514.                    1) Null root.
  6515.                    2) Null key.
  6516.                    3) Null found.
  6517.  
  6518.  
  6519.  
  6520.  
  6521.  
  6522.  
  6523.  
  6524.  
  6525.  
  6526.  
  6527.  
  6528.  
  6529.  
  6530.  
  6531.  
  6532.  
  6533.  
  6534.  
  6535.  
  6536.  
  6537.  
  6538.  
  6539.  
  6540.  
  6541.                                           - 98 -
  6542.  
  6543.  
  6544.  
  6545.  
  6546.                                  Copyright Ron Albury 1988
  6547.  
  6548.              EXAMPLE
  6549.  
  6550.                 #include "salve.h"
  6551.  
  6552.                 main()
  6553.                 {
  6554.                    struct UserRec *u;
  6555.                    Tnode  node;
  6556.                    Troot  root;
  6557.  
  6558.                    /* open the tree */
  6559.                    /* add records to the tree */
  6560.                       :   :   :
  6561.  
  6562.                    /* find a node in the tree *
  6563.                    gets (key)
  6564.                    node = Tfind (root, key, &u);
  6565.  
  6566.                    /* use the tree */
  6567.                       :   :   :
  6568.  
  6569.                    /* close the tree */
  6570.                 }
  6571.  
  6572.  
  6573.  
  6574.  
  6575.  
  6576.  
  6577.  
  6578.  
  6579.  
  6580.  
  6581.  
  6582.  
  6583.  
  6584.  
  6585.  
  6586.  
  6587.  
  6588.  
  6589.  
  6590.  
  6591.  
  6592.  
  6593.  
  6594.  
  6595.  
  6596.  
  6597.  
  6598.  
  6599.  
  6600.  
  6601.  
  6602.  
  6603.  
  6604.  
  6605.  
  6606.  
  6607.                                           - 99 -
  6608.  
  6609.  
  6610.  
  6611.  
  6612.                                  Copyright Ron Albury 1988
  6613.  
  6614.           FUNCTION Tfind_first
  6615.                    Tfind_first
  6616.  
  6617.              PURPOSE
  6618.  
  6619.                 Finds the  smallest element  (based on  the supplied compare
  6620.              function) in the indicated tree.
  6621.  
  6622.              PARAMETERS
  6623.  
  6624.                 Root:  (Input)
  6625.                    The root of the tree being accessed.
  6626.  
  6627.                 Found: (Output)
  6628.                    The smallest data element in the tree.
  6629.  
  6630.              RETURNS
  6631.  
  6632.                 A Tnode pointer
  6633.                    Success: Tree node of the found element.
  6634.                    Failure: NULL (empty tree)
  6635.  
  6636.              PROTOTYPE
  6637.  
  6638.                 Tnode Tfind_first
  6639.                    (Troot troot, void **found);
  6640.  
  6641.              DEBUG
  6642.  
  6643.                 The debug library (only) will report:
  6644.                    1) Null root.
  6645.                    2) Null found.
  6646.  
  6647.              EXAMPLE
  6648.  
  6649.                 #include "salve.h"
  6650.  
  6651.                 main()
  6652.                 {
  6653.                    struct UserRec *u;
  6654.                    Tnode  node;
  6655.                    Troot  root;
  6656.  
  6657.                    /* open the tree */
  6658.                    /* add records to the tree */
  6659.                       :   :   :
  6660.  
  6661.                    /* find the first node in the tree *
  6662.                    node = Tfind_first (root, &u);
  6663.  
  6664.                    /* use the tree */
  6665.                       :   :   :
  6666.  
  6667.                    /* close the tree */
  6668.                 }
  6669.  
  6670.  
  6671.  
  6672.  
  6673.  
  6674.                                           - 100 -
  6675.  
  6676.  
  6677.  
  6678.  
  6679.                                  Copyright Ron Albury 1988
  6680.  
  6681.           FUNCTION Tfind_next
  6682.                    Tfind_next
  6683.  
  6684.              PURPOSE
  6685.  
  6686.                 Finds the next data element in the indicated tree.
  6687.  
  6688.              PARAMETERS
  6689.  
  6690.                 Root:  (Input)
  6691.                    The root of the tree being accessed.
  6692.  
  6693.                 Node:
  6694.                    The tree node prior to the requested element.
  6695.  
  6696.                 Found: (Output)
  6697.                    The data  element in  the tree following the indicated
  6698.                    node..
  6699.  
  6700.              RETURNS
  6701.  
  6702.                 A Tnode pointer
  6703.                    Success: Tree node of the found element.
  6704.                    Failure: NULL (indicated node was the last node in the
  6705.                             tree).
  6706.  
  6707.              PROTOTYPE
  6708.  
  6709.                 Tnode Tfind_next
  6710.                    (Troot troot, Tnode prior, void **found);
  6711.  
  6712.              DEBUG
  6713.  
  6714.                 The debug library (only) will report:
  6715.                    1) Null root.
  6716.                    2) Null prior.
  6717.                    3) Null found.
  6718.  
  6719.  
  6720.  
  6721.  
  6722.  
  6723.  
  6724.  
  6725.  
  6726.  
  6727.  
  6728.  
  6729.  
  6730.  
  6731.  
  6732.  
  6733.  
  6734.  
  6735.  
  6736.  
  6737.  
  6738.  
  6739.  
  6740.  
  6741.                                           - 101 -
  6742.  
  6743.  
  6744.  
  6745.  
  6746.                                  Copyright Ron Albury 1988
  6747.  
  6748.              EXAMPLE
  6749.  
  6750.                 #include "salve.h"
  6751.  
  6752.                 main()
  6753.                 {
  6754.                    struct UserRec *u;
  6755.                    Tnode  node;
  6756.                    Troot  root;
  6757.  
  6758.                    /* open the tree */
  6759.                       :   :   :
  6760.                    /* add records to the tree */
  6761.                       :   :   :
  6762.  
  6763.                    /* find the first node in the tree */
  6764.                    node = Tfind_first (root, &u);
  6765.  
  6766.                    /* traverse the rest of the tree in order */
  6767.                    while (node != NULL)
  6768.                    {
  6769.                       /* use the node */
  6770.                          :   :   :
  6771.  
  6772.                       /* get the next node */
  6773.                       node = Tfind_next (root, node, &u);
  6774.                    }
  6775.  
  6776.                    /* use the tree */
  6777.                       :   :   :
  6778.  
  6779.                    /* close the tree */
  6780.                 }
  6781.  
  6782.  
  6783.  
  6784.  
  6785.  
  6786.  
  6787.  
  6788.  
  6789.  
  6790.  
  6791.  
  6792.  
  6793.  
  6794.  
  6795.  
  6796.  
  6797.  
  6798.  
  6799.  
  6800.  
  6801.  
  6802.  
  6803.  
  6804.  
  6805.  
  6806.  
  6807.                                           - 102 -
  6808.  
  6809.  
  6810.  
  6811.  
  6812.                                  Copyright Ron Albury 1988
  6813.  
  6814.           FUNCTION Tfind_node
  6815.                    Tfind_node
  6816.  
  6817.              PURPOSE
  6818.  
  6819.                 Finds the  data element  associated with  a tree node.  This
  6820.              function is  useful if you store the tree nodes in another data
  6821.              management structure (such as a hash table).
  6822.  
  6823.              PARAMETERS
  6824.  
  6825.                 Node:  (Input)
  6826.                    The tree  node to  be used  in finding  the  requested
  6827.                    data.
  6828.  
  6829.                 Found: (Output)
  6830.                    The data element located at that node.
  6831.  
  6832.              RETURNS
  6833.  
  6834.                 void.
  6835.  
  6836.              PROTOTYPE
  6837.  
  6838.                 void Tfind_node
  6839.                    (Tnode node, void **found);
  6840.  
  6841.              DEBUG
  6842.  
  6843.                 The debug library (only) will report:
  6844.                    1) Null node.
  6845.                    2) Null found.
  6846.  
  6847.  
  6848.  
  6849.  
  6850.  
  6851.  
  6852.  
  6853.  
  6854.  
  6855.  
  6856.  
  6857.  
  6858.  
  6859.  
  6860.  
  6861.  
  6862.  
  6863.  
  6864.  
  6865.  
  6866.  
  6867.  
  6868.  
  6869.  
  6870.  
  6871.  
  6872.  
  6873.  
  6874.                                           - 103 -
  6875.  
  6876.  
  6877.  
  6878.  
  6879.                                  Copyright Ron Albury 1988
  6880.  
  6881.              EXAMPLE
  6882.  
  6883.                 #include "salve.h"
  6884.  
  6885.                 main()
  6886.                 {
  6887.                    struct UserRec *u;
  6888.                    Tnode  node;
  6889.                    Troot  root;
  6890.  
  6891.                    /* open the tree */
  6892.                    /* add records to the tree */
  6893.                    /* cross reference them in a hash table */
  6894.  
  6895.                    /* find a node through the hash table *
  6896.                       :   :   :
  6897.  
  6898.                    /* get the data associated with it */
  6899.                    Tfind_node (node, &u);
  6900.  
  6901.                    /* delete the node from the tree and the table */
  6902.                       :   :   :
  6903.  
  6904.                    /* close the tree */
  6905.                 }
  6906.  
  6907.  
  6908.  
  6909.  
  6910.  
  6911.  
  6912.  
  6913.  
  6914.  
  6915.  
  6916.  
  6917.  
  6918.  
  6919.  
  6920.  
  6921.  
  6922.  
  6923.  
  6924.  
  6925.  
  6926.  
  6927.  
  6928.  
  6929.  
  6930.  
  6931.  
  6932.  
  6933.  
  6934.  
  6935.  
  6936.  
  6937.  
  6938.  
  6939.  
  6940.                                           - 104 -
  6941.  
  6942.  
  6943.  
  6944.  
  6945.                                  Copyright Ron Albury 1988
  6946.  
  6947.           FUNCTION Topen
  6948.                    Topen
  6949.  
  6950.              PURPOSE
  6951.  
  6952.                 Opens  a   binary  tree  and  creates  the  data  structures
  6953.              necessary for  its management.   As with a list, each tree must
  6954.              be opened before it can be used in your program.  This function
  6955.              is required  before any  other of  the tree  functions  can  be
  6956.              performed.   Trees can be used to index a linked list (the data
  6957.              item stored  in the  tree is  the link  node) or  to store data
  6958.              directly.
  6959.  
  6960.              PARAMETERS
  6961.  
  6962.                 Root: (Output)
  6963.                    The root  or handle  of the  tree being  opened.  This
  6964.                    parameter is referenced by all other tree functions.
  6965.  
  6966.                 Comp: (Input)
  6967.                    The comparison  function to  be used  with this  tree.
  6968.                    This function  should return zero for equal, less than
  6969.                    zero if  the data  is less  than the  key, and greater
  6970.                    than zero if the data is greater than the key.
  6971.  
  6972.              RETURNS
  6973.  
  6974.                 Integer indicating status of open.
  6975.                    0 = Success.
  6976.  
  6977.              PROTOTYPE
  6978.  
  6979.                 int Topen
  6980.                    (Troot *root, KCmpFnc comp);
  6981.  
  6982.              DEBUG
  6983.  
  6984.                 Both libraries will report:
  6985.                    1) Null root pointer.
  6986.                    2) Null comparison function.
  6987.                    3) Malloc failure.
  6988.  
  6989.  
  6990.  
  6991.  
  6992.  
  6993.  
  6994.  
  6995.  
  6996.  
  6997.  
  6998.  
  6999.  
  7000.  
  7001.  
  7002.  
  7003.  
  7004.  
  7005.  
  7006.  
  7007.                                           - 105 -
  7008.  
  7009.  
  7010.  
  7011.  
  7012.                                  Copyright Ron Albury 1988
  7013.  
  7014.              EXAMPLE
  7015.  
  7016.                 #include "salve.h"
  7017.  
  7018.                 int compare (void *data, void *key)
  7019.                 {
  7020.                   /* compare the data with the key */
  7021.                 }
  7022.  
  7023.                 main()
  7024.                 {
  7025.                    int   status;
  7026.                    Troot root;
  7027.  
  7028.                    status = Topen (&root, compare);
  7029.                       :   :   :
  7030.                 }
  7031.  
  7032.  
  7033.  
  7034.  
  7035.  
  7036.  
  7037.  
  7038.  
  7039.  
  7040.  
  7041.  
  7042.  
  7043.  
  7044.  
  7045.  
  7046.  
  7047.  
  7048.  
  7049.  
  7050.  
  7051.  
  7052.  
  7053.  
  7054.  
  7055.  
  7056.  
  7057.  
  7058.  
  7059.  
  7060.  
  7061.  
  7062.  
  7063.  
  7064.  
  7065.  
  7066.  
  7067.  
  7068.  
  7069.  
  7070.  
  7071.  
  7072.  
  7073.                                           - 106 -
  7074.  
  7075.  
  7076.  
  7077.  
  7078.                                  Copyright Ron Albury 1988
  7079.  
  7080.           FUNCTION Tremove
  7081.                    Tremove
  7082.  
  7083.              PURPOSE
  7084.  
  7085.                 Removes a node and data element from the indicated tree.
  7086.  
  7087.              PARAMETERS
  7088.  
  7089.                 Root: (Input)
  7090.                    The root of the tree being accessed.
  7091.  
  7092.                 Node: (Input)
  7093.                    The tree node of the element to remove.
  7094.  
  7095.              RETURNS
  7096.  
  7097.                 Integer indicating status of the removal.
  7098.                    0 = Success.
  7099.                    1 = Corrupted memory, or indicated element is not part
  7100.                        of this tree.
  7101.  
  7102.              PROTOTYPE
  7103.  
  7104.                 void Tremove
  7105.                    (Troot root, Tnode node);
  7106.  
  7107.              DEBUG
  7108.  
  7109.                 The debug library (only) will report:
  7110.                    1) Null root.
  7111.                    2) Null drop node.
  7112.  
  7113.  
  7114.  
  7115.  
  7116.  
  7117.  
  7118.  
  7119.  
  7120.  
  7121.  
  7122.  
  7123.  
  7124.  
  7125.  
  7126.  
  7127.  
  7128.  
  7129.  
  7130.  
  7131.  
  7132.  
  7133.  
  7134.  
  7135.  
  7136.  
  7137.  
  7138.  
  7139.  
  7140.                                           - 107 -
  7141.  
  7142.  
  7143.  
  7144.  
  7145.                                  Copyright Ron Albury 1988
  7146.  
  7147.              EXAMPLE
  7148.  
  7149.                 #include "salve.h"
  7150.  
  7151.                 main()
  7152.                 {
  7153.                    struct UserRec *u;
  7154.                    Tnode  node;
  7155.                    Troot  root;
  7156.  
  7157.                    /* open the tree */
  7158.                    /* add records to the tree */
  7159.                       :   :   :
  7160.  
  7161.                    /* find a node in the tree *
  7162.                    gets (key)
  7163.                    node = Tfind (root, key, &u);
  7164.  
  7165.                    /* delete that node */
  7166.                    Tremove (root, node)
  7167.  
  7168.                    /* use the tree */
  7169.                       :   :   :
  7170.  
  7171.                    /* close the tree */
  7172.                 }
  7173.  
  7174.  
  7175.  
  7176.  
  7177.  
  7178.  
  7179.  
  7180.  
  7181.  
  7182.  
  7183.  
  7184.  
  7185.  
  7186.  
  7187.  
  7188.  
  7189.  
  7190.  
  7191.  
  7192.  
  7193.  
  7194.  
  7195.  
  7196.  
  7197.  
  7198.  
  7199.  
  7200.  
  7201.  
  7202.  
  7203.  
  7204.  
  7205.  
  7206.                                           - 108 -
  7207.  
  7208.  
  7209.  
  7210.  
  7211.                                  Copyright Ron Albury 1988
  7212.  
  7213.           FUNCTION Ttest
  7214.                    Ttest
  7215.  
  7216.              PURPOSE
  7217.  
  7218.                 Tests a  tree node  to detect memory corruption or to verify
  7219.              that the element is from the indicated tree.
  7220.  
  7221.              PARAMETERS
  7222.  
  7223.                 Root:
  7224.                    The root of the tree being accessed.
  7225.  
  7226.                 Node:
  7227.                    The node of the tree to be tested.
  7228.  
  7229.              RETURNS
  7230.  
  7231.                 Integer indicating status of test.
  7232.                    0 = Success.
  7233.                    1 = Corrupted memory, or indicated element is not part
  7234.                        of this tree.
  7235.  
  7236.              PROTOTYPE
  7237.  
  7238.                 int Ttest
  7239.                    (Troot troot, Tnode node);
  7240.  
  7241.              DEBUG
  7242.  
  7243.                 The debug library (only) will report:
  7244.                    1) Null root.
  7245.                    2) Null node.
  7246.  
  7247.  
  7248.  
  7249.  
  7250.  
  7251.  
  7252.  
  7253.  
  7254.  
  7255.  
  7256.  
  7257.  
  7258.  
  7259.  
  7260.  
  7261.  
  7262.  
  7263.  
  7264.  
  7265.  
  7266.  
  7267.  
  7268.  
  7269.  
  7270.  
  7271.  
  7272.  
  7273.                                           - 109 -
  7274.  
  7275.  
  7276.  
  7277.  
  7278.                                  Copyright Ron Albury 1988
  7279.  
  7280.              EXAMPLE
  7281.  
  7282.                 #include "salve.h"
  7283.  
  7284.                 main()
  7285.                 {
  7286.                    int    status;
  7287.                    struct UserRec *u;
  7288.                    Tnode  node;
  7289.                    Troot  root;
  7290.  
  7291.                    /* open the tree */
  7292.                       :   :   :
  7293.                    /* add records to the tree */
  7294.                       :   :   :
  7295.  
  7296.                    /* find the first node in the tree */
  7297.                    node = Tfind_first (root, &u);
  7298.  
  7299.                    /* test that node for corruption */
  7300.                    status = Ttest (root, node);
  7301.  
  7302.                       :   :   :
  7303.                 }
  7304.  
  7305.  
  7306.  
  7307.  
  7308.  
  7309.  
  7310.  
  7311.  
  7312.  
  7313.  
  7314.  
  7315.  
  7316.  
  7317.  
  7318.  
  7319.  
  7320.  
  7321.  
  7322.  
  7323.  
  7324.  
  7325.  
  7326.  
  7327.  
  7328.  
  7329.  
  7330.  
  7331.  
  7332.  
  7333.  
  7334.  
  7335.  
  7336.  
  7337.  
  7338.  
  7339.                                           - 110 -
  7340.  
  7341.  
  7342.  
  7343.  
  7344.                                  Copyright Ron Albury 1988
  7345.  
  7346.           UTILITIES
  7347.           UTILITIES
  7348.  
  7349.                 There are  plans to  provide a number of utility programs to
  7350.              assist in  the design  and development of application using the
  7351.              Salve Data  Management Functions.   However, at this time there
  7352.              is only  one function  and one  program  which  are  ready  for
  7353.              release.
  7354.  
  7355.  
  7356.  
  7357.  
  7358.  
  7359.  
  7360.  
  7361.  
  7362.  
  7363.  
  7364.  
  7365.  
  7366.  
  7367.  
  7368.  
  7369.  
  7370.  
  7371.  
  7372.  
  7373.  
  7374.  
  7375.  
  7376.  
  7377.  
  7378.  
  7379.  
  7380.  
  7381.  
  7382.  
  7383.  
  7384.  
  7385.  
  7386.  
  7387.  
  7388.  
  7389.  
  7390.  
  7391.  
  7392.  
  7393.  
  7394.  
  7395.  
  7396.  
  7397.  
  7398.  
  7399.  
  7400.  
  7401.  
  7402.  
  7403.  
  7404.  
  7405.  
  7406.                                           - 111 -
  7407.  
  7408.  
  7409.  
  7410.  
  7411.                                  Copyright Ron Albury 1988
  7412.  
  7413.           FUNCTION ERROR_REPORT
  7414.                    ERROR_REPORT
  7415.  
  7416.              PURPOSE
  7417.  
  7418.                 This is  the general error logging utility used in the SALVE
  7419.              debug library.   Whenever  a 'debug'  error is  detected,  this
  7420.              function is called.  This function performs I/O to file stderr.
  7421.              This   output   can   be   re-directed   using   the   function
  7422.              SET_ERROR_LOG.  You can also replace this function with another
  7423.              one of your own design.
  7424.  
  7425.              PARAMETERS
  7426.  
  7427.                 Filename:
  7428.                    The name of the file the error was detected in.
  7429.  
  7430.                 Line:
  7431.                    The line of the file where the error occurred.
  7432.  
  7433.                 Format:
  7434.                    The format  to use  with fprintf  when displaying  the
  7435.                    error.   This format  may (or may not) include a %d to
  7436.                    display the (optional) error code parameter.
  7437.  
  7438.                 Errcode:
  7439.                    An optional integer error code.
  7440.  
  7441.              RETURNS
  7442.  
  7443.                 void.
  7444.  
  7445.              PROTOTYPE
  7446.  
  7447.                 void error_report
  7448.                    (char *filename, int line, char *format, int errcode);
  7449.  
  7450.              EXAMPLE
  7451.  
  7452.                 #include "salve.h"
  7453.  
  7454.                 main()
  7455.                 {
  7456.                    int  status;
  7457.  
  7458.                    /* do something */
  7459.                    status = something();
  7460.  
  7461.                    /* report possible error */
  7462.                    if (status) error_report (__FILE__, __LINE__,
  7463.                     "Error doing something = %d\n", status);
  7464.  
  7465.                       :   :   :
  7466.                 }
  7467.  
  7468.  
  7469.  
  7470.  
  7471.  
  7472.  
  7473.                                           - 112 -
  7474.  
  7475.  
  7476.  
  7477.  
  7478.                                  Copyright Ron Albury 1988
  7479.  
  7480.           FUNCTION SET_ERROR_LOG
  7481.                    SET_ERROR_LOG
  7482.  
  7483.              PURPOSE
  7484.  
  7485.                 Redirects debugging output.
  7486.  
  7487.              PARAMETERS
  7488.  
  7489.                 Filename:
  7490.                    The name of the file to use for debug logging.
  7491.  
  7492.              RETURNS
  7493.  
  7494.                 Integer indicating status of test.
  7495.                    0  = Success.
  7496.                    !0 = Unable to open file.
  7497.  
  7498.              PROTOTYPE
  7499.  
  7500.                 int set_error_log
  7501.                    (char *filename);
  7502.  
  7503.              EXAMPLE
  7504.  
  7505.                 #include "salve.h"
  7506.  
  7507.                 main()
  7508.                 {
  7509.                    int  status;
  7510.  
  7511.                    /* direct error logging to file err.log */
  7512.                    status = set_error_log ("err.log");
  7513.  
  7514.                       :   :   :
  7515.                 }
  7516.  
  7517.  
  7518.  
  7519.  
  7520.  
  7521.  
  7522.  
  7523.  
  7524.  
  7525.  
  7526.  
  7527.  
  7528.  
  7529.  
  7530.  
  7531.  
  7532.  
  7533.  
  7534.  
  7535.  
  7536.  
  7537.  
  7538.  
  7539.  
  7540.                                           - 113 -
  7541.  
  7542.  
  7543.  
  7544.  
  7545.                                  Copyright Ron Albury 1988
  7546.  
  7547.           PROGRAM LLDEF
  7548.                   LLDEF
  7549.  
  7550.              PURPOSE
  7551.  
  7552.                 The LLDEF program will automatically generate custom include
  7553.              files for your programs.  These include files will allow you to
  7554.              perform strong type checking for the different data types being
  7555.              controlled through the Salve Data Management Routines.
  7556.  
  7557.                 LLDEF will  create an  include file  with an  alias  and  an
  7558.              appropriate function  prototype for  the each  of the specified
  7559.              data management routines.  Use of this file allows the compiler
  7560.              to more easily detect errors in your source code.
  7561.  
  7562.              COMMAND LINE PARAMETERS
  7563.  
  7564.                 LLDEF can be invoked with 1-n argument pairs.  Each argument
  7565.              pair consists of:
  7566.  
  7567.                 Function Set:
  7568.                    One or  more  of  the  letters  LHTMB,  indicating  if
  7569.                    aliases should  be generated for the List, Hash, Tree,
  7570.                                                         L     H     T    
  7571.                    Matrix and/or Bit set routines (e.g LH or LMT).
  7572.                    M             B                                
  7573.  
  7574.                 Record Types:
  7575.                    A list  of one  or more pointer typedef's for which to
  7576.                    generate the  aliases.   It is best to use short names
  7577.                    here.
  7578.  
  7579.              EXAMPLE
  7580.  
  7581.                 If you were managing lists of the following data structure:
  7582.                    typedef struct
  7583.                    {
  7584.                        int  a;
  7585.                        int  b;
  7586.                         :   :
  7587.                    }
  7588.                        Pxrec, *Px;
  7589.  
  7590.  
  7591.              and wanted  to manage  them in  a list  you  would  invoke  the
  7592.              program with the following command line:
  7593.                    LLDEF L Px > PX.H
  7594.  
  7595.  
  7596.                 This tells the program that you want PX aliases and function
  7597.              declarations for  each of  the list  management routines.   The
  7598.              Ladd_first function  is aliased as PxLadd_first, the Ladd_order
  7599.              function is  aliased as  PxLadd_order, etc..   The  void  *data
  7600.              parameters for  the aliased  functions are  changed to Px *data
  7601.              parameters.  Once you have corrected any compilation errors the
  7602.              prototypes detect,  a simple  change of a compile time constant
  7603.              'un-aliases' the  functions and  allows the linker to find them
  7604.              in the library.
  7605.  
  7606.  
  7607.  
  7608.  
  7609.                                           - 114 -
  7610.  
  7611.  
  7612.  
  7613.  
  7614.                                  Copyright Ron Albury 1988
  7615.  
  7616.                 The generated  declarations are  written to standard output,
  7617.              and must  be re-directed  to disk  file for  inclusion in  your
  7618.              programs.
  7619.  
  7620.           
  7621.  
  7622.  
  7623.  
  7624.  
  7625.  
  7626.  
  7627.  
  7628.  
  7629.  
  7630.  
  7631.  
  7632.  
  7633.  
  7634.  
  7635.  
  7636.  
  7637.  
  7638.  
  7639.  
  7640.  
  7641.  
  7642.  
  7643.  
  7644.  
  7645.  
  7646.  
  7647.  
  7648.  
  7649.  
  7650.  
  7651.  
  7652.  
  7653.  
  7654.  
  7655.  
  7656.  
  7657.  
  7658.  
  7659.  
  7660.  
  7661.  
  7662.  
  7663.  
  7664.  
  7665.  
  7666.  
  7667.  
  7668.  
  7669.  
  7670.  
  7671.  
  7672.  
  7673.  
  7674.  
  7675.                                           - 115 -
  7676.  
  7677.  
  7678.  
  7679.  
  7680.  
  7681.  
  7682.  
  7683.  
  7684.             INTRODUCTION                                               1
  7685.                 SALVE SOFTWARE                                         1
  7686.                 SHAREWARE                                              1
  7687.                 DESIGN APPROACH                                        2
  7688.                 USE OF POINTERS IN FUNCTIONS                           5
  7689.                 FILES AND LIBRARIES INCLUDED                           5
  7690.                 USER SUPPLIED FUNCTIONS                                6
  7691.             BIT SET CLASS                                              8
  7692.                 FUNCTION Badd                                          9
  7693.                 FUNCTION Bcard                                        10
  7694.                 FUNCTION Bclose                                       11
  7695.                 FUNCTION Bcomplement                                  12
  7696.                 FUNCTION Bdifference                                  13
  7697.                 FUNCTION Bduplicate                                   15
  7698.                 FUNCTION Bequal                                       16
  7699.                 FUNCTION Bfind_next                                   17
  7700.                 FUNCTION Bfor_each                                    19
  7701.                 FUNCTION Bintersect                                   21
  7702.                 FUNCTION Bopen                                        23
  7703.                 FUNCTION Bremove                                      25
  7704.                 FUNCTION Btest_in                                     26
  7705.                 FUNCTION Btoggle                                      27
  7706.                 FUNCTION Bunion                                       28
  7707.             HASH TABLE CLASS                                          30
  7708.                 FUNCTION Hadd                                         31
  7709.                 FUNCTION Hcard                                        33
  7710.                 FUNCTION Hclose                                       34
  7711.                 FUNCTION Hfind                                        35
  7712.                 FUNCTION Hfind_node                                   37
  7713.                 FUNCTION Hopen                                        39
  7714.                 FUNCTION Hremove                                      41
  7715.                 FUNCTION Htest                                        43
  7716.             LINKED LIST CLASS                                         45
  7717.                 FUNCTION Ladd_after                                   46
  7718.                 FUNCTION Ladd_before                                  48
  7719.                 FUNCTION Ladd_first                                   50
  7720.                 FUNCTION Ladd_last                                    52
  7721.                 FUNCTION Ladd_order                                   54
  7722.                 FUNCTION Lcard                                        56
  7723.                 FUNCTION Lclose                                       57
  7724.                 FUNCTION Lfind                                        58
  7725.                 FUNCTION Lfind_after                                  60
  7726.                 FUNCTION Lfind_before                                 62
  7727.                 FUNCTION Lfind_first                                  64
  7728.                 FUNCTION Lfind_last                                   65
  7729.                 FUNCTION Lfind_next                                   66
  7730.                 FUNCTION Lfind_node                                   68
  7731.                 FUNCTION Lmake_first                                  70
  7732.                 FUNCTION Lopen                                        72
  7733.                 FUNCTION Lremove                                      74
  7734.                 FUNCTION Ltest                                        76
  7735.  
  7736.  
  7737.  
  7738.  
  7739.  
  7740.  
  7741.  
  7742.  
  7743.  
  7744.  
  7745.  
  7746.  
  7747.  
  7748.  
  7749.  
  7750.             SPARSE MATRIX CLASS                                       78
  7751.                 FUNCTION Madd                                         79
  7752.                 FUNCTION Mcard                                        81
  7753.                 FUNCTION Mclose                                       82
  7754.                 FUNCTION Mfind                                        83
  7755.                 FUNCTION Mfind_node                                   85
  7756.                 FUNCTION Mopen                                        87
  7757.                 FUNCTION Mremove                                      89
  7758.                 FUNCTION Mtest                                        91
  7759.             BINARY TREE CLASS                                         93
  7760.                 FUNCTION Tadd                                         94
  7761.                 FUNCTION Tcard                                        96
  7762.                 FUNCTION Tclose                                       97
  7763.                 FUNCTION Tfind                                        98
  7764.                 FUNCTION Tfind_first                                 100
  7765.                 FUNCTION Tfind_next                                  101
  7766.                 FUNCTION Tfind_node                                  103
  7767.                 FUNCTION Topen                                       105
  7768.                 FUNCTION Tremove                                     107
  7769.                 FUNCTION Ttest                                       109
  7770.             UTILITIES                                                111
  7771.                 FUNCTION error_report                                112
  7772.                 FUNCTION set_error_log                               113
  7773.                 PROGRAM LLDEF                                        114
  7774.  
  7775.                   
  7776.  
  7777.  
  7778.  
  7779.  
  7780.  
  7781.  
  7782.  
  7783.  
  7784.  
  7785.  
  7786.  
  7787.  
  7788.  
  7789.  
  7790.  
  7791.  
  7792.  
  7793.  
  7794.  
  7795.  
  7796.  
  7797.  
  7798.  
  7799.  
  7800.  
  7801.  
  7802.  
  7803.  
  7804.  
  7805.  
  7806.  
  7807.  
  7808.  
  7809.  
  7810.